diff options
60 files changed, 1647 insertions, 915 deletions
diff --git a/.bzrignore b/.bzrignore index b3fe7accece..7c1105386e2 100644 --- a/.bzrignore +++ b/.bzrignore @@ -190,6 +190,7 @@ db-*.*.* dbug/user.t extra/comp_err extra/my_print_defaults +extra/mysql_install extra/perror extra/replace extra/resolve_stack_dump @@ -287,6 +288,7 @@ libmysqld/sql_command libmysqld/sql_crypt.cc libmysqld/sql_db.cc libmysqld/sql_delete.cc +libmysqld/sql_do.cc libmysqld/sql_handler.cc libmysqld/sql_insert.cc libmysqld/sql_lex.cc @@ -367,6 +369,7 @@ scripts/mysql_config scripts/mysql_convert_table_format scripts/mysql_explain_log scripts/mysql_find_rows +scripts/mysql_fix_extensions scripts/mysql_fix_privilege_tables scripts/mysql_install_db scripts/mysql_setpermission @@ -398,6 +401,7 @@ sql-bench/test-connect sql-bench/test-create sql-bench/test-insert sql-bench/test-select +sql-bench/test-transactions sql-bench/test-wisconsin sql/.gdbinit sql/gen_lex_hash @@ -445,6 +449,3 @@ vio/test-ssl vio/test-sslclient vio/test-sslserver vio/viotest-ssl -sql-bench/test-transactions -libmysqld/sql_do.cc -extra/mysql_install diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok new file mode 100644 index 00000000000..e678faba910 --- /dev/null +++ b/BitKeeper/etc/logging_ok @@ -0,0 +1,40 @@ +Administrator@co3064164-a. +Administrator@co3064164-a.rochd1.qld.optushome.com.au +Administrator@fred. +Miguel@light.local +Sinisa@sinisa.nasamreza.org +ahlentz@co3064164-a.rochd1.qld.optusnet.com.au +arjen@co3064164-a.bitbike.com +davida@isil.mysql.com +heikki@donna.mysql.fi +jani@hynda.mysql.fi +jani@janikt.pp.saunalahti.fi +jcole@abel.spaceapes.com +jcole@main.burghcom.com +jcole@tetra.spaceapes.com +miguel@light.local +monty@bitch.mysql.fi +monty@donna.mysql.fi +monty@hundin.mysql.fi +monty@tik.mysql.fi +monty@tramp.mysql.fi +monty@work.mysql.com +mwagner@evoq.mwagner.org +paul@central.snake.net +paul@teton.kitebird.com +root@x3.internalnet +sasha@mysql.sashanet.com +serg@serg.mysql.com +tfr@sarvik.tfr.cafe.ee +tim@bitch.mysql.fi +tim@black.box +tim@hundin.mysql.fi +tim@threads.polyesthetic.msg +tim@white.box +tim@work.mysql.com +tonu@hundin.mysql.fi +tonu@volk.internalnet +tonu@x153.internalnet +tonu@x3.internalnet +jcole@sarvik.tfr.cafe.ee +venu@work.mysql.com diff --git a/Docs/manual.texi b/Docs/manual.texi index 72752cdfccd..c8390f6aa30 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -108,10 +108,10 @@ END-INFO-DIR-ENTRY @node Top, Introduction, (dir), (dir) @ifinfo -This is a manual for MySQL. This version is about the -@value{mysql_version} version of MySQL. You can find a manual -about any older version of MySQL in the binary or source -distribution for that version. +This is a manual for the MySQL Database System. +This version is about the @value{mysql_version} version of MySQL Server. +You can find a specific manual for any older version of MySQL Server +in the binary or source distribution for that version. @end ifinfo @menu @@ -144,38 +144,40 @@ distribution for that version. @cindex overview @cindex general information -@code{MySQL (TM)} is a very fast, multi-threaded, multi-user, and robust -@code{SQL} (@code{Structured Query Language}) database server. -MySQL is intended for mission-critical, heavy load production systems -as well as for embedding into mass-deployed software. +The @code{MySQL (TM)} software delivers a very fast, multi-threaded, +multi-user, and robust @code{SQL} (@code{Structured Query Language}) +database server. +MySQL Server is intended for mission-critical, heavy load production +systems as well as for embedding into mass-deployed software. @code{MySQL} is a trademark of @code{MySQL AB}. -MySQL has @code{Dual licensing}, you can use MySQL free of charge -under the @code{GNU GENERAL PUBLIC LICENSE} +The MySQL software has @code{Dual licensing}, you can use MySQL Server +free of charge under the @code{GNU GENERAL PUBLIC LICENSE} (@uref{http://www.gnu.org/licenses/}). -You can also purchase commercial MySQL licenses from @code{MySQL AB} -if you do not wish to be bound by the terms of the GPL. +You can also purchase commercial MySQL Server licenses from +@code{MySQL AB} if you do not wish to be bound by the terms of the GPL. @xref{Licensing and Support}. The MySQL web site (@uref{http://www.mysql.com/}) provides the latest -information about MySQL. +information about the MySQL software. The following list describes some useful sections of the manual: @itemize @bullet @item -For information about the company behind MySQL, see -@ref{What is MySQL AB}. +For information about the company behind the MySQL Database Server, +see @ref{What is MySQL AB}. @item -For a discussion of MySQL's capabilities, see @ref{Features}. +For a discussion about the capabilities of the MySQL Database Server, +see @ref{Features}. @item For installation instructions, see @ref{Installing}. @item -For tips on porting MySQL to new architectures or operating -systems, see @ref{Porting}. +For tips on porting the MySQL Database Software to new architectures +or operating systems, see @ref{Porting}. @item For information about upgrading from a Version 3.23 release, see @@ -186,7 +188,8 @@ For information about upgrading from a Version 3.22 release, see @ref{Upgrading-from-3.22}. @item -For a tutorial introduction to MySQL, see @ref{Tutorial}. +For a tutorial introduction to the MySQL Database Server, +see @ref{Tutorial}. @item For examples of SQL and benchmarking information, see the benchmarking @@ -215,7 +218,7 @@ The @code{mysqlbug} script should be used to generate bug reports. For source distributions, the @code{mysqlbug} script can be found in the @file{scripts} directory. For binary distributions, @code{mysqlbug} can be found in the @file{bin} directory. If you have found a sensitive -security bug in MySQL, you should send an e-mail to +security bug in MySQL Server, you should send an e-mail to @email{security@@mysql.com}. @cindex errors, reporting @@ -247,7 +250,8 @@ This is the MySQL reference manual; it documents MySQL Version @value{mysql_version}. Being a reference manual, it does not provide general instruction on SQL or relational database concepts. -As MySQL is work in progress, the manual gets updated frequently. +As the MySQL Database Software is work in progress, the manual gets +updated frequently. The most recent version of this manual is available at @uref{http://www.mysql.com/documentation/} in many different formats, currently there are Texinfo, plain text, Info, HTML, PostScript, and @@ -417,7 +421,7 @@ that builds its business providing services around the MySQL database. @xref{What is MySQL AB}. The MySQL web site (@uref{http://www.mysql.com/}) -provides the latest information about MySQL and MySQL AB. +provides the latest information about MySQL software and MySQL AB. @table @asis @@ -427,7 +431,7 @@ A database is a structured collection of data. It may be anything from a simple shopping list to a picture gallery or the vast amounts of information in a corporate network. To add, access, and process data stored in a computer database, you need a database management system -such as MySQL. Since computers are very good at handling large +such as MySQL Server. Since computers are very good at handling large amounts of data, database management plays a central role in computing, as stand-alone utilities, or as parts of other applications. @@ -436,60 +440,62 @@ as stand-alone utilities, or as parts of other applications. @item MySQL is a relational database management system. A relational database stores data in separate tables rather than putting -all the data in one big storeroom. This adds speed and flexibility. The -tables are linked by defined relations making it possible to combine -data from several tables on request. The SQL part of MySQL -stands for "Structured Query Language" - the most common standardised -language used to access databases. +all the data in one big storeroom. This adds speed and flexibility. +The tables are linked by defined relations making it possible to combine +data from several tables on request. The @code{SQL} part of +``@code{MySQL}'' stands for ``@code{Structured Query Language}'' +- the most common standardised language used to access databases. @cindex relational databases, defined @cindex SQL, defined -@item MySQL is Open Source Software. +@item MySQL Software is Open Source. Open Source means that it is possible for anyone to use and modify. -Anybody can download MySQL from the Internet and use it +Anybody can download the MySQL software from the Internet and use it without paying anything. Anybody so inclined can study the source code -and change it to fit their needs. MySQL uses the GPL (GNU +and change it to fit their needs. The MySQL software uses the GPL (GNU General Public License) @uref{http://www.gnu.org/licenses/}, to define what you may and may not do with the software in different situations. If you -feel uncomfortable with the GPL or need to embed MySQL into a commercial +feel uncomfortable with the GPL or need to embed MySQL code into a commercial application you can buy a commercially licensed version from us. @xref{MySQL server licenses}. @cindex Open Source, defined @cindex General Public License -@item Why use MySQL? +@item Why use the MySQL Database Server? -MySQL is very fast, reliable, and easy to use. If that is what -you are looking for, you should give it a try. MySQL also has a +The MySQL Database Server is very fast, reliable, and easy to use. +If that is what you are looking for, you should give it a try. +MySQL Server also has a practical set of features developed in close cooperation with -our users. You can find a performance comparison of MySQL +our users. You can find a performance comparison of MySQL Server to some other database managers on our benchmark page. @xref{MySQL Benchmarks}. -MySQL was originally developed to handle large databases +MySQL Server was originally developed to handle large databases much faster than existing solutions and has been successfully used in highly demanding production environments for several years. Though -under constant development, MySQL today offers a rich and +under constant development, MySQL Server today offers a rich and useful set of functions. The connectivity, speed, and security make -MySQL highly suited for accessing databases on the Internet. +MySQL Server highly suited for accessing databases on the Internet. -@item The technical features of MySQL +@item The technical features of MySQL Server -For advanced technical information, see @ref{Reference}. MySQL is -a client/server system that consists of a multi-threaded SQL server -that supports different backends, several different client programs and -libraries, administrative tools, and several programming interfaces. +For advanced technical information, see @ref{Reference}. The MySQL +Database Software is a client/server system that consists of a +multi-threaded SQL server that supports different backends, several +different client programs and libraries, administrative tools, and +several programming interfaces. -We also provide MySQL as a multi-threaded library which you can +We also provide MySQL Server as a multi-threaded library which you can link into your application to get a smaller, faster, easier to manage product. -@item MySQL has a lot of contributed software available. +@item There is a lot of contributed MySQL software available. It is very likely that you will find that your favorite application or -language already supports MySQL. +language already supports the MySQL Database Server. @end table @@ -524,7 +530,7 @@ flexible enough for our needs. This resulted in a new SQL interface to our database but with almost the same API interface as @code{mSQL}. This API was chosen to ease porting of third-party code. -The derivation of the name MySQL is not perfectly clear. Our base +The derivation of the name @code{MySQL} is not perfectly clear. Our base directory and a large number of our libraries and tools have had the prefix ``my'' for well over 10 years. However, Monty's daughter (some years younger) is also named My. Which of the two gave its name to MySQL is @@ -538,7 +544,7 @@ still a mystery, even for us. @cindex features of MySQL The following list describes some of the important characteristics -of MySQL. @xref{MySQL 4.0 In A Nutshell}. +of the MySQL Database Software. @xref{MySQL 4.0 In A Nutshell}. @c This list is too technical and should be divided into one feature @c list comparable to commercial competition and a very technical on @@ -549,7 +555,7 @@ of MySQL. @xref{MySQL 4.0 In A Nutshell}. @item Written in C and C++. Tested with a broad range of different compilers. @item -No memory leaks. MySQL has been tested with Purify, a commercial +No memory leaks. The MySQL code has been tested with Purify, a commercial memory leakage detector. @item Works on many different platforms. @xref{Which OS}. @@ -643,13 +649,13 @@ password traffic is encrypted when you connect to a server. @item Scalability and Limits @itemize @bullet @item -Handles large databases. We are using MySQL with some +Handles large databases. We are using MySQL Server with some databases that contain 50,000,000 records and we know of users that -uses MySQL with 60,000 tables and about 5,000,000,000 rows. +uses MySQL Server with 60,000 tables and about 5,000,000,000 rows. @item Up to 32 indexes per table are allowed. Each index may consist of 1 to 16 columns or parts of columns. The maximum index width is 500 bytes -(this may be changed when compiling MySQL). An index may use a prefix +(this may be changed when compiling MySQL Server). An index may use a prefix of a @code{CHAR} or @code{VARCHAR} field. @end itemize @@ -681,7 +687,7 @@ string columns are case insensitive. Sorting is done according to the chosen character set (the Swedish way by default). It is possible to change this when the MySQL server is started up. To see an example of very advanced sorting, look at the -Czech sorting code. MySQL supports many different character sets +Czech sorting code. MySQL Server supports many different character sets that can be specified at compile and run time. @end itemize @@ -714,26 +720,27 @@ very active in identifying problems as well as reporting types of use. Original code stems back from the early 80s, providing a stable code base, and the ISAM table format remains backwards compatible. -At TcX, the predecessor of MySQL AB, MySQL has worked in projects +At TcX, the predecessor of MySQL AB, MySQL code has worked in projects since mid-1996, without any problems. -When MySQL was released to a wider public, we noticed that there were +When the MySQL Database Software was released to a wider public, +we noticed that there were some pieces of ``untested code'' that were quickly found by the new users who made different types of queries from us. Each new release has had fewer portability problems (even though each new release has had many new features). -Each release of MySQL has been usable. There have only been problems +Each release of the MySQL Server has been usable. There have only been problems when users try code from the ``gray zones.'' Naturally, new users don't know what the gray zones are; this section attempts to indicate those that are currently known. -The descriptions mostly deal with Version 3.23 of MySQL. +The descriptions mostly deal with Version 3.23 of MySQL Server. All known and reported bugs are fixed in the latest version, with the exception of those listed in the bugs section, which are things that are design-related. @xref{Bugs}. -MySQL design is multi-layered with independent modules. Some of the -newer modules are listed below with an indication of how well-tested -each of them is: +The MySQL Server design is multi-layered with independent modules. +Some of the newer modules are listed below with an indication of how +well-tested each of them is: @cindex modules, list of @@ -750,7 +757,7 @@ used in some large, heavy load production systems. @item @code{BDB} tables -- Gamma The @code{Berkeley DB} code is very stable, but we are still improving -the @code{BDB} transactional table handler interface in MySQL, so it +the @code{BDB} transactional table handler interface in MySQL Server, so it will take some time before this is as well tested as the other table types. @@ -817,7 +824,7 @@ On Linux 2.2 you can get bigger tables than 2G by using the LFS patch for the ext2 file system. On Linux 2.4 there exists also patches for ReiserFS to get support for big files. -This means that the table size for MySQL is normally limited by +This means that the table size for MySQL databases is normally limited by the operating system. By default, MySQL tables have a maximum size of about 4G. You can @@ -851,14 +858,14 @@ tables}. @cindex compliance, Y2K @cindex date functions, Y2K compliance -MySQL itself has no problems with Year 2000 (Y2K) compliance: +The MySQL Server itself has no problems with Year 2000 (Y2K) compliance: @itemize @bullet @item -MySQL uses Unix time functions and has no problems with dates +MySQL Server uses Unix time functions and has no problems with dates until @code{2069}; all 2-digit years are regarded to be in the range @code{1970} to @code{2069}, which means that if you store @code{01} in a -@code{year} column, MySQL treats it as @code{2001}. +@code{year} column, MySQL Server treats it as @code{2001}. @item All MySQL date functions are stored in one file @file{sql/time.cc} @@ -870,7 +877,7 @@ can store years @code{0} and @code{1901} to @code{2155} in 1 byte and display them using 2 or 4 digits. @end itemize -You may run into problems with applications that use MySQL in a +You may run into problems with applications that use MySQL Server in a way that is not Y2K-safe. For example, many old applications store or manipulate years using 2-digit values (which are ambiguous) rather than 4-digit values. This problem may be compounded by applications that use @@ -880,7 +887,7 @@ Unfortunately, these problems may be difficult to fix, because different applications may be written by different programmers, each of whom may use a different set of conventions and date-handling functions. -Here is a simple demonstration illustrating that MySQL doesn't have +Here is a simple demonstration illustrating that MySQL Server doesn't have any problems with dates until the year 2030: @example @@ -940,8 +947,8 @@ range up to only @code{2030-01-01}. @code{TIMESTAMP} has a range of @code{1970} to @code{2030} on 32-bit machines (signed value). On 64-bit machines it handles times up to @code{2106} (unsigned value). -Even though MySQL is Y2K-compliant, it is your responsibility to -provide unambiguous input. See @ref{Y2K issues} for MySQL's rules +Even though MySQL Server is Y2K-compliant, it is your responsibility to +provide unambiguous input. See @ref{Y2K issues} for MySQL Server's rules for dealing with ambiguous date input data (data containing 2-digit year values). @@ -961,9 +968,9 @@ We are a virtual organisation with people in a dozen countries around the world. We communicate extensively over the net every day with each other and with our users, supporters and partners. -We are dedicated to developing MySQL and spreading our database to new -users. MySQL AB owns the copyright to the MySQL source code, the MySQL -logo and trademark and this manual. @xref{What-is}. +We are dedicated to developing the MySQL software and spreading our +database to new users. MySQL AB owns the copyright to the MySQL source +code, the MySQL logo and trademark and this manual. @xref{What-is}. @menu * MySQL AB business model and services:: The Business Model and Services of MySQL AB @@ -972,7 +979,7 @@ logo and trademark and this manual. @xref{What-is}. The MySQL core values show our dedication to MySQL and Open Source. -We want MySQL to be: +We want the MySQL Database Software to be: @itemize @bullet @item The best and the most widely used database in the world. @@ -1095,22 +1102,22 @@ Program, please e-mail @email{certification@@mysql.com}. @node Business Services Consulting, Business Services Commercial licenses, Business Services Training, MySQL AB business model and services @subsubsection Consulting MySQL AB and its Authorised Partners offer consulting services to -users of MySQL and to those who embed MySQL in their own software, -all over the world. +users of the MySQL Server and to those who embed the MySQL Server +in their own software, all over the world. Our consultants can help you design and tune your databases, construct efficient queries, tune your platform for optimal performance, resolve migration issues, set up replication, build robust transactional applications, and more. -We also help customers embed MySQL in their products and applications -for large-scale deployment. +We also help customers embed the MySQL Server in their products and +applications for large-scale deployment. Our consultants work in close collaboration with our development team which ensures the technical quality of our professional services. Consulting assignments range from 2-day power start sessions to projects that span weeks and months. Our expertise does not only cover -MySQL, but extends into programming and scripting languages such as -PHP, Perl and more. +MySQL Server, but extends into programming and scripting languages +such as PHP, Perl and more. If you are interested in our consulting services or want to become a consulting partner, please visit the consulting section of our web site @@ -1122,10 +1129,10 @@ consulting staff at @email{consulting@@mysql.com}. @node Business Services Commercial licenses, Business Services Partnering, Business Services Consulting, MySQL AB business model and services @subsubsection Commercial Licenses The MySQL database is released under the @code{GNU General Public License} -(@code{GPL}). This means that MySQL can be used free of charge under the -GPL. If you do not want to be bound by the GPL terms (like the requirement -that your own application becomes GPL as well), you may purchase a -commercial license for the same product from MySQL AB at +(@code{GPL}). This means that the MySQL software can be used free of charge +under the GPL. If you do not want to be bound by the GPL terms (like the +requirement that your own application becomes GPL as well), you may purchase +a commercial license for the same product from MySQL AB at @uref{https://order.mysql.com/}. Since MySQL AB owns the copyright to the MySQL server, we are able to employ @code{Dual Licensing} which means that the same product is @@ -1135,14 +1142,14 @@ For details about when a commercial license is required, please see @ref{MySQL server licenses}. We also sell commercial licenses of third-party Open Source GPL software -that adds value to MySQL. A good example is the @code{InnoDB} +that adds value to the MySQL Server. A good example is the @code{InnoDB} transactional table handler that offers ACID support, row-level locking, crash recovery, multiversioning, foreign key support, and more. @node Business Services Partnering, Business Services Advertising, Business Services Commercial licenses, MySQL AB business model and services @subsubsection Partnering -@cindex partnering with MySQL +@cindex partnering with MySQL AB MySQL AB has a worldwide partner program that covers training courses, support, consulting, solutions, publications plus reselling and distributing MySQL and related products. Partners get visibility on the @@ -1193,8 +1200,8 @@ For press service and inquiries not covered in our News releases @email{press@@mysql.com}. If you have a valid support contract with MySQL AB; you will get -timely, precise answers to your technical questions about MySQL. -For more information, see @ref{Support}. +timely, precise answers to your technical questions about the MySQL +software. For more information, see @ref{Support}. You can order your support contract at @uref{https://order.mysql.com/}, or send an email to @email{sales@@mysql.com}. @@ -1254,7 +1261,7 @@ attention to the appropriate mailing list. Reports of errors (often called bugs), as well as questions and comments, should be sent to the mailing list at @email{mysql@@lists.mysql.com}. If you have found a sensitive -security bug in MySQL, you should send an e-mail to +security bug in the MySQL Server, you should send an e-mail to @email{security@@mysql.com}. @xref{Bug reports}. @@ -1311,13 +1318,13 @@ unique problems direct from the software engineers who code the MySQL database engine. We try to take a broad and inclusive view of technical support. Almost -any problem involving MySQL is important to us if it's important to you. +any problem involving MySQL software is important to us if it's important to you. Typically customers seek help on how to get different commands and utilities to work, remove performance bottlenecks, restore crashed systems, understand operating system or networking impacts on MySQL, set-up best practices for backup and recovery, utilise APIs, etc. Our support covers only the MySQL server and our own utilities, not -third-party products that access MySQL, though we try to help with +third-party products that access the MySQL server, though we try to help with these where we can. Detailed information about our various support options is given at @@ -1328,7 +1335,7 @@ our sales staff at @email{sales@@mysql.com}. Technical support is like life insurance. You can live happily without it for years, but when your hour arrives it becomes critically important, yet it's too late to buy it! -If you use MySQL for important applications and encounter sudden +If you use MySQL Server for important applications and encounter sudden troubles, it might take too long to figure out all the answers yourself. You may need immediate access to the most experienced MySQL troubleshooters available, those employed by MySQL AB. @@ -1456,7 +1463,7 @@ code. @item When you distribute a non-GPL application that ONLY works with the MySQL -server and ships it with MySQL. This type of solution is actually +server and ship it with the MySQL server. This type of solution is actually considered to be linking even if it's done over a network. @item @@ -1467,7 +1474,7 @@ source code as required under the GPL license. When you want to support the further development of the MySQL database even if you don't formally need a commercial license. Purchasing support directly from MySQL AB is another good way of contributing to the -development of MySQL, with immediate advantages for you. +development of the MySQL software, with immediate advantages for you. @xref{Support}. @end itemize @@ -1497,7 +1504,7 @@ resulting product under GPL. @item When you distribute the MySQL server source code bundled with other -programs that are not linked to or dependant on MySQL for their +programs that are not linked to or dependant on MySQL Server for their functionality even if you sell the distribution commercially. @item @@ -1505,7 +1512,7 @@ When using the MySQL server internally in your company. @item When include the MySQL client code in a commercial program. -The client part of MySQL is licensed under the LGPL +The client part of the MySQL software is licensed under the LGPL @code{GNU Lesser General Public License}. The formal terms of the LGPL license can be found at @uref{http://www.gnu.org/licenses/}. @@ -1529,29 +1536,31 @@ to our @code{announce} mailing list so that they can be aware of critical issues that may be relevant for their MySQL installations. Note that even if an ISP does not have a commercial license for -MySQL, they should at least give their customers read access to the +MySQL Server, they should at least give their customers read access to the source of the MySQL installation so that the customers can verify that it is patched correctly. @item @cindex web server, running @cindex running a web server -When you use MySQL in conjunction with a Web server, you do not need -a commercial license. This is true even if you run a commercial Web -server that uses MySQL, because you are not selling an embedded MySQL -version yourself. However, in this case we would like you to -purchase MySQL support, because MySQL is helping your enterprise. -@end itemize - -If your use of MySQL does not require a commercial license, we -encourage you to purchase support from MySQL AB anyway. This way -you contribute towards MySQL development and also gain immediate -advantages for yourself. @xref{Support}. - -If you use MySQL in a commercial context such that you profit by -its use, we ask that you further the development of MySQL by -purchasing some level of support. We feel that if MySQL helps -your business, it is reasonable to ask that you help MySQL. +When you use the MySQL Database Software in conjunction with a Web +server, you do not need a commercial license. This is true even if +you run a commercial Web server that uses MySQL Server, because you +are not selling an embedded MySQL version yourself. However, in this +case we would like you to purchase MySQL support, because the MySQL +software is helping your enterprise. +@end itemize + +If your use of MySQL database software does not require a commercial +license, we encourage you to purchase support from MySQL AB anyway. +This way you contribute towards MySQL development and also gain +immediate advantages for yourself. @xref{Support}. + +If you use the MySQL database software in a commercial context such +that you profit by its use, we ask that you further the development +of the MySQL software by purchasing some level of support. We feel +that if the MySQL database helps your business, it is reasonable to +ask that you help MySQL AB. (Otherwise, if you ask us support questions, you are not only using for free something into which we've put a lot a work, you're asking us to provide free support, too.) @@ -1675,7 +1684,7 @@ Please see @xref{Business Services Partnering,,Partnering}. MySQL AB welcomes references to the MySQL database, but note that the word @code{MySQL} is a trademark of MySQL AB. Because of this, you should append the trademark symbol @code{TM} to the first or most prominent use -of the word MySQL in a text and where appropriate use a statement that +of the word @code{MySQL} in a text and where appropriate use a statement that @code{MySQL} is a trademark of MySQL AB. Please refer to our trademark policy at @uref{http://www.mysql.com/company/trademark.html} for details. @@ -1694,12 +1703,12 @@ domain names is not allowed without written permission from MySQL AB. Dateline: 16 October 2001, Uppsala, Sweden Long promised by MySQL AB and long awaited by our users, -MySQL 4.0 is now available in alpha version for download from +MySQL Server 4.0 is now available in alpha version for download from @uref{http://www.mysql.com/} and our mirrors. -Main new features of MySQL 4.0 are geared towards our existing -business and community users, enhancing MySQL as the solution -for mission-critical, heavy load database systems. +Main new features of MySQL Server 4.0 are geared towards our existing +business and community users, enhancing the MySQL database software +as the solution for mission-critical, heavy load database systems. Other new features target the users of embedded databases. @menu @@ -1715,25 +1724,25 @@ Other new features target the users of embedded databases. @node Nutshell Stepwise Rollout, Nutshell Ready for Immediate Development Use, MySQL 4.0 In A Nutshell, MySQL 4.0 In A Nutshell @subsection Stepwise Rollout -The rollout of MySQL 4.0 will come in several steps, with +The rollout of MySQL Server 4.0 will come in several steps, with the first version labelled 4.0.0 already containing most of the new features. Additional features will be incorporated into -MySQL 4.0.1, 4.0.2 onwards; very probably within two months, +MySQL 4.0.1, 4.0.2 onwards; very probably within a couple of months, MySQL 4.0 will be labelled beta. Further new features will then be added in MySQL 4.1, which is targeted for alpha release -in December/January. +in early 2002. @node Nutshell Ready for Immediate Development Use, Nutshell Embedded MySQL, Nutshell Stepwise Rollout, MySQL 4.0 In A Nutshell @subsection Ready for Immediate Development Use Users are not recommended to switch their production systems -to MySQL 4.0 until it is released in beta version later Q4/2001. +to MySQL Server 4.0 until it is released in beta version. However, even the initial release has passed our extensive test suite without any errors on any of the platforms we test on. Due to the large number of new features, we thus recommend -MySQL 4.0 even in alpha form for development use, with -the release schedule of MySQL 4.0 being such that it will +MySQL Server 4.0 even in alpha form for development use, with +the release schedule of MySQL Server 4.0 being such that it will reach stable state before the deployment of user applications now under development. @@ -1741,17 +1750,17 @@ now under development. @node Nutshell Embedded MySQL, Nutshell Other features, Nutshell Ready for Immediate Development Use, MySQL 4.0 In A Nutshell @subsection Embedded MySQL -@code{libmysqld} makes MySQL suitable for a vastly expanded realm of +@code{libmysqld} makes MySQL Server suitable for a vastly expanded realm of applications. Using the embedded MySQL server library, one can -embed MySQL into various applications and electronics devices, where +embed MySQL Server into various applications and electronics devices, where the end user has no knowledge of there actually being an underlying -database. Embedded MySQL is ideal for use behind +database. Embedded MySQL Server is ideal for use behind the scenes in internet appliances, public kiosks, turn-key hardware/ software combination units, high performance internet servers, self-contained databases distributed on CD-ROM etc. Many embedded MySQL users will benefit from the @emph{dual licensing} -scheme of MySQL, where besides the GPL license also commercial +scheme of the MySQL software, where besides the GPL license also commercial licensing is available for those not wishing to be bound by the GPL. The embedded MySQL library uses the same interface as the normal client library, so it is convenient and easy to use. @@ -1762,7 +1771,8 @@ client library, so it is convenient and easy to use. @itemize @bullet @item -MySQL 4.0 further increases @emph{the speed of MySQL} in a number of areas, +Version 4.0 further increases @emph{the speed of MySQL Server} +in a number of areas, such as bulk @code{INSERT}s, searching on packed indices, creation of @code{FULLTEXT} indices as well as @code{COUNT(DISTINCT)}. @@ -1772,7 +1782,7 @@ standard MySQL server, including full support for @code{transactions} and @code{row-level locking}. @item -MySQL 4.0 will support secure traffic between the client and the server, +MySQL Server 4.0 will support secure traffic between the client and the server, greatly increasing security against malicious intrusion and unauthorised access. Web applications being a cornerstone of MySQL use, web developers have been able to use SSL to secure the traffic between the @@ -1780,7 +1790,7 @@ the end user browser and the Web application, be it written in PHP, Perl, ASP or using any other web development tool. However, the traffic between the development tool and the mysqld server process has been protected only by virtue of them being processes -residing on computers within the same firewall. In MySQL 4.0, +residing on computers within the same firewall. In MySQL Server 4.0, the @emph{mysqld} server daemon process can itself use @code{Secure Sockets Layer} (@code{SSL}), thus enabling secure traffic to MySQL databases from, say, a Windows @@ -1793,9 +1803,9 @@ Umlauts in the same order as German telephone books. @item Features to simplify @code{migration} from other database systems to MySQL -include @code{TRUNCATE TABLE} (like in Oracle) and @code{IDENTITY} as a +Server include @code{TRUNCATE TABLE} (like in Oracle) and @code{IDENTITY} as a synonym for automatically incremented keys (like in Sybase). Many users will -also be happy to learn that MySQL now supports the @code{UNION} statement, +also be happy to learn that MySQL Server now supports the @code{UNION} statement, a long awaited standard SQL feature. @item @@ -1815,12 +1825,12 @@ possible to know how many rows a query would have returned without a @node Nutshell Future features, Nutshell 4.1 development release, Nutshell Other features, MySQL 4.0 In A Nutshell @subsection Future MySQL 4.0 Features -For the upcoming MySQL 4.0 releases (4.0.1, 4.0.2 and onwards), expect -the following features now still under development: +For the upcoming MySQL Server 4.0 releases (4.0.1, 4.0.2 and onwards), +expect the following features now still under development: @itemize @bullet @item -Mission-critical, heavy-load users of MySQL will appreciate +Mission-critical, heavy-load users of MySQL Server will appreciate the additions to our replication system and our online hot backup. Later versions of 4.0 will include @code{fail-safe replication}; already in existing 4.0.0, the @code{LOAD DATA FROM MASTER} command @@ -1835,11 +1845,11 @@ mysqld parameters (startup options) can soon be set without taking down the servers. @item -The new @code{FULLTEXT} search properties of MySQL 4.0 enables the use -of @code{FULLTEXT} indexing of large text masses with both binary and +The new @code{FULLTEXT} search properties of MySQL Server 4.0 enables the +use of @code{FULLTEXT} indexing of large text masses with both binary and natural language searching logic. Users can customise minimal word length and define their own stop word lists in any human language, -enabling a new set of applications to be built on MySQL. +enabling a new set of applications to be built on MySQL Server. @item Many read-heavy applications will benefit from @@ -1855,17 +1865,18 @@ in the client. @subsection MySQL 4.1, The Following Development Release Internally, through a new .frm file format for table definitions, -MySQL 4.0 lays the foundation for the new features of MySQL 4.1, +MySQL Server 4.0 lays the foundation for the new features of MySQL Server 4.1, such as @code{nested subqueries}, @code{stored procedures}, and @code{foreign key integrity rules}, which form the top of the wish list for many of our customers. Along with those, we will also include simpler additions, such as multi-table @code{UPDATE} statements. -After those additions, critics of MySQL have to be more imaginative +After those additions, critics of the MySQL Database Server have +to be more imaginative than ever in pointing out deficiencies in the MySQL Database Management System. For long already known for its stability, -speed, and ease of use, MySQL will then match the requirement +speed, and ease of use, MySQL Server will then match the requirement checklist of very demanding buyers. @@ -1918,25 +1929,25 @@ comment on, rate, or buy them. While this manual (particularly the online version) is still the right place for up to date technical information, its primary goal is to contain everything there is to know about -MySQL. It's sometimes nice to have a bound book to read in -bed or while you travel. +the MySQL database system. It's sometimes nice to have a bound +book to read in bed or while you travel. By purchasing a book through the hyperlinks provided, you -will contribute to the development of MySQL. +will contribute to the development of the MySQL software. @item Development -This portal has links to sites that are using MySQL for various +This portal has links to sites that are using MySQL Server for various purposes, with a description of each site. This information can -give you an idea of who uses MySQL and how MySQL can fulfill -their requirements. +give you an idea of who uses the MySQL database software and how +MySQL Server can fulfill their requirements. Do let us know about @emph{your} site or success story too! @item Software Here you can find and download a multitude of applications and -wrappers that make use of MySQL. +wrappers that make use of the MySQL server. @item Distributions From here you can find the various Linux distributions and other -software packages that contain MySQL. +software packages that contain the MySQL software. @item Consultants Here you can find information about MySQL Consultants. @@ -2034,7 +2045,7 @@ On this list you should only post a full, repeatable bug report using the @code{mysqlbug} script (if you are running on Windows, you should include a description of the operating system and the MySQL version). Preferably, you should test the problem using the latest stable or development -version of MySQL before posting! Anyone should be able to repeat the +version of MySQL Server before posting! Anyone should be able to repeat the bug by just using @code{mysql test < script} on the included test case. All bugs posted on this list will be corrected or documented in the next MySQL release! If there are only small code changes involved, we @@ -2051,20 +2062,20 @@ can also discuss MySQL development and post patches. A digest version of the @code{internals} list. @item @email{java-subscribe@@lists.mysql.com} java -Discussion about MySQL and Java. Mostly about the JDBC drivers. +Discussion about the MySQL server and Java. Mostly about the JDBC drivers. @item @email{java-digest-subscribe@@lists.mysql.com} java-digest A digest version of the @code{java} list. @item @email{win32-subscribe@@lists.mysql.com} win32 -All things concerning MySQL on Microsoft operating systems such as -Win95, Win98, NT, and Win2000. +All things concerning the MySQL software on Microsoft operating systems +such as Win95, Win98, NT, and Win2000. @item @email{win32-digest-subscribe@@lists.mysql.com} win32-digest A digest version of the @code{win32} list. @item @email{myodbc-subscribe@@lists.mysql.com} myodbc -All things about connecting to MySQL with ODBC. +All things about connecting to the MySQL server with ODBC. @item @email{myodbc-digest-subscribe@@lists.mysql.com} myodbc-digest A digest version of the @code{myodbc} list. @@ -2076,7 +2087,7 @@ All things concerning programming with the C++ API to MySQL. A digest version of the @code{plusplus} list. @item @email{msql-mysql-modules-subscribe@@lists.mysql.com} msql-mysql-modules -A list about the Perl support in MySQL. msql-mysql-modules +A list about the Perl support for MySQL with msql-mysql-modules. @item @email{msql-mysql-modules-digest-subscribe@@lists.mysql.com} msql-mysql-modules-digest A digest version of the @code{msql-mysql-modules} list. @@ -2186,7 +2197,7 @@ list. Note that on this list you should only post a full, repeatable bug report using the @code{mysqlbug} script. If you are running on Windows, you should include a description of the operating system and the MySQL version. Preferably, you should test the problem using -the latest stable or development version of MySQL before +the latest stable or development version of MySQL Server before posting! Anyone should be able to repeat the bug by just using ``@code{mysql test < script}'' on the included test case or run the shell or perl script that is included in the bug report. All bugs @@ -2209,7 +2220,7 @@ first time. The most common errors are that people don't indicate the version number of the MySQL distribution they are using, or don't indicate what -platform they have MySQL installed on (including the platform +platform they have the MySQL server installed on (including the platform version number). This is highly relevant information, and in 99 cases out of 100 the bug report is useless without it! Very often we get questions like, ``Why doesn't this work for me?'' then we find that the feature @@ -2274,7 +2285,7 @@ Sometimes the amount of memory (real and virtual) is relevant. If in doubt, include these values. @item -If you are using a source distribution of MySQL, the name and +If you are using a source distribution of the MySQL software, the name and version number of the compiler used is needed. If you have a binary distribution, the distribution name is needed. @@ -2343,7 +2354,7 @@ archive to @uref{ftp://support.mysql.com/pub/mysql/secret/}. Then send a short description of the problem to @email{bugs@@lists.mysql.com}. @item -If you think that MySQL produces a strange result from a query, +If you think that the MySQL server produces a strange result from a query, include not only the result, but also your opinion of what the result should be, and an account describing the basis for your opinion. @@ -2402,17 +2413,17 @@ problem yourself. @item If you get a @code{parse error}, please check your syntax closely! If you can't find something wrong with it, it's extremely likely that your -current version of MySQL doesn't support the query you are +current version of MySQL Server doesn't support the query you are using. If you are using the current version and the manual at @uref{http://www.mysql.com/doc/} doesn't cover the -syntax you are using, MySQL doesn't support your query. In this +syntax you are using, MySQL Server doesn't support your query. In this case, your only options are to implement the syntax yourself or e-mail @email{mysql-licensing@@mysql.com} and ask for an offer to implement it! If the manual covers the syntax you are using, but you have an older version -of MySQL, you should check the MySQL change history to see +of MySQL Server, you should check the MySQL change history to see when the syntax was implemented. In this case, you have the option of -upgrading to a newer version of MySQL. @xref{News}. +upgrading to a newer version of MySQL Server. @xref{News}. @item If you have a problem such that your data appears corrupt or you get @@ -2431,11 +2442,11 @@ it's much easier for us to provide you with a fix for the problem. @xref{What is crashing}. @item -If possible, download and install the most recent version of MySQL +If possible, download and install the most recent version of MySQL Server and check whether or not it solves your problem. All versions of -MySQL are thoroughly tested and should work without problems. We -believe in making everything as backward compatible as possible, and you -should be able to switch MySQL versions without any hassle. +the MySQL software are thoroughly tested and should work without problems. +We believe in making everything as backward compatible as possible, +and you should be able to switch MySQL versions without any hassle. @xref{Which version}. @end itemize @@ -2488,34 +2499,34 @@ Many users don't read mail with a browser! @cindex ANSI SQL92, extensions to This section describes how MySQL relates to the ANSI SQL standards. -MySQL has many extensions to the ANSI SQL standards, and here you +MySQL Server has many extensions to the ANSI SQL standards, and here you will find out what they are, and how to use them. You will also find -information about functionality missing from MySQL, and how to work +information about functionality missing from MySQL Server, and how to work around some differences. -Our goal is to not, without a very good reason, restrict MySQL usability +Our goal is to not, without a very good reason, restrict MySQL Server usability for any usage. Even if we don't have the resources to do development for every possible use, we are always willing to help and offer -suggestions to people that is trying to use MySQL in new territories. +suggestions to people that is trying to use MySQL Server in new territories. One of our main goals with the product is to continue to work towards ANSI 99 compliancy, but without sacrificing speed or reliability. We are not afraid to add extensions to SQL or support for non-SQL -features if this greatly increase the usability of MySQL for a big -part of our users. (The new @code{HANDLER} interface in MySQL 4.0 +features if this greatly increase the usability of MySQL Server for a big +part of our users. (The new @code{HANDLER} interface in MySQL Server 4.0 is an example of this strategy. @xref{HANDLER}.) We will continue to support transactional and not transactional databases to satisfy both heavy web/logging usage and mission critical 24/7 usage. -MySQL was designed from the start to work with medium large databases +MySQL Server was designed from the start to work with medium large databases (10-100 million rows / about 100 MB per table) on small computer -systems. We will continue to extend MySQL to both work even better +systems. We will continue to extend MySQL Server to both work even better with terabyte size databases, but we are also doing work to make it possible to compile a reduced MySQL version that is more suitable for hand held -devices and embedded usage. The compact design of MySQL makes both of -these directions possible without any conflicts in the source tree. +devices and embedded usage. The compact design of the MySQL server makes both +of these directions possible without any conflicts in the source tree. We are currently not targeting real time support or clustered databases (even if you can already do a lot of things with our replication @@ -2554,7 +2565,7 @@ but without concessions to speed and quality of the code. @cindex ANSI mode, running If you start @code{mysqld} with the @code{--ansi} option, the following -behavior of MySQL changes: +behavior of MySQL Server changes: @itemize @bullet @item @@ -2565,7 +2576,7 @@ You can have any number of spaces between a function name and the @samp{(}. This forces all function names to be treated as reserved words. @item -@samp{"} will be an identifier quote character (like the MySQL +@samp{"} will be an identifier quote character (like the MySQL Server @samp{`} quote character) and not a string quote character. @item @@ -2586,11 +2597,11 @@ IGNORE_SPACE,SERIALIZE,ONLY_FULL_GROUP_BY}. @subsection MySQL Extensions to ANSI SQL92 @cindex hints -MySQL includes some extensions that you probably will not find in +MySQL Server includes some extensions that you probably will not find in other SQL databases. Be warned that if you use them, your code will not be portable to other SQL servers. In some cases, you can write code that includes MySQL extensions, but is still portable, by using comments -of the form @code{/*! ... */}. In this case, MySQL will parse and +of the form @code{/*! ... */}. In this case, MySQL Server will parse and execute the code within the comment as it would any other MySQL statement, but other SQL servers will ignore the extensions. For example: @@ -2607,7 +2618,7 @@ CREATE /*!32302 TEMPORARY */ TABLE (a int); @end example The above means that if you have Version 3.23.02 or newer, then MySQL -will use the @code{TEMPORARY} keyword. +Server will use the @code{TEMPORARY} keyword. MySQL extensions are listed below: @@ -2629,7 +2640,7 @@ comparisons to be done according to the ASCII order used on the MySQL server host. @item -MySQL maps each database to a directory under the MySQL +MySQL Server maps each database to a directory under the MySQL data directory, and tables within a database to filenames in the database directory. @@ -2643,7 +2654,7 @@ This has a few implications: @itemize @minus @item -Database names and table names are case sensitive in MySQL on +Database names and table names are case sensitive in MySQL Server on operating systems that have case-sensitive filenames (like most Unix systems). @xref{Name case sensitivity}. @@ -2661,7 +2672,7 @@ and @file{.frm} files to which the table corresponds. In SQL statements, you can access tables from different databases with the @code{db_name.tbl_name} syntax. Some SQL servers provide the same functionality but call this @code{User space}. -MySQL doesn't support tablespaces as in: +MySQL Server doesn't support tablespaces as in: @code{create table ralph.my_table...IN my_tablespace}. @item @@ -2751,18 +2762,18 @@ One can specify @code{ASC} and @code{DESC} with @code{GROUP BY}. @item To make it easier for users who come from other SQL environments, -MySQL supports aliases for many functions. For example, all +MySQL Server supports aliases for many functions. For example, all string functions support both ANSI SQL syntax and ODBC syntax. @item -MySQL understands the @code{||} and @code{&&} operators to mean -logical OR and AND, as in the C programming language. In MySQL, +MySQL Server understands the @code{||} and @code{&&} operators to mean +logical OR and AND, as in the C programming language. In MySQL Server, @code{||} and @code{OR} are synonyms, as are @code{&&} and @code{AND}. -Because of this nice syntax, MySQL doesn't support +Because of this nice syntax, MySQL Server doesn't support the ANSI SQL @code{||} operator for string concatenation; use @code{CONCAT()} instead. Because @code{CONCAT()} takes any number of arguments, it's easy to convert use of the @code{||} operator to -MySQL. +MySQL Server. @item @code{CREATE DATABASE} or @code{DROP DATABASE}. @@ -2795,7 +2806,7 @@ operators. @item @code{CONCAT()} or @code{CHAR()} with one argument or more than two -arguments. (In MySQL, these functions can take any number of +arguments. (In MySQL Server, these functions can take any number of arguments.) @item The @code{BIT_COUNT()}, @code{CASE}, @code{ELT()}, @@ -2832,8 +2843,8 @@ SELECT @@t1:=(@@t2:=1)+@@t3:=4,@@t1,@@t2,@@t3; @node Differences from ANSI, Bugs, Extensions to ANSI, Compatibility @subsection MySQL Differences Compared to ANSI SQL92 -We try to make MySQL follow the ANSI SQL standard and the -ODBC SQL standard, but in some cases MySQL does things +We try to make MySQL Server follow the ANSI SQL standard and the +ODBC SQL standard, but in some cases MySQL Server does things differently: @itemize @bullet @@ -2867,7 +2878,7 @@ extra conditions in this case. @end menu For a prioritised list indicating when new extensions will be added to -MySQL, you should consult the online MySQL TODO list at +MySQL Server, you should consult the online MySQL TODO list at @uref{http://www.mysql.com/documentation/manual.php?section=TODO}. That is the latest version of the TODO list in this manual. @xref{TODO}. @@ -2877,9 +2888,9 @@ That is the latest version of the TODO list in this manual. @xref{TODO}. @cindex sub-selects -MySQL currently only supports nested queries of the form @code{INSERT -... SELECT ...} and @code{REPLACE ... SELECT ...}. You can however use -the function @code{IN()} in other contexts. +MySQL Server currently only supports nested queries of the form +@code{INSERT ... SELECT ...} and @code{REPLACE ... SELECT ...}. +You can however use the function @code{IN()} in other contexts. Sub-selects are scheduled for implementation in Version 4.x. Meanwhile, you can often rewrite the query without a sub-select: @@ -2913,7 +2924,7 @@ to hold the subquery. In some cases, however this option will not work. The most frequently encountered of these cases arises with @code{DELETE} statements, for which standard SQL does not support joins (except in sub-selects). For this situation there are two options -available until subqueries are supported by MySQL. +available until subqueries are supported by MySQL Server. The first option is to use a procedural programming language (such as Perl or PHP) to submit a @code{SELECT} query to obtain the primary keys @@ -2940,9 +2951,9 @@ second instance of the interpreter: shell> mysql --skip-column-names mydb < myscript.sql | mysql mydb @end example -MySQL 4.0 supports multi-table deletes that can be used to efficiently -delete rows based on information from one table or even from many tables -at the same time. +MySQL Server 4.0 supports multi-table deletes that can be used to +efficiently delete rows based on information from one table or even +from many tables at the same time. @node ANSI diff SELECT INTO TABLE, ANSI diff Transactions, ANSI diff Sub-selects, Differences from ANSI @@ -2950,8 +2961,8 @@ at the same time. @findex SELECT INTO TABLE -MySQL doesn't yet support the Oracle SQL extension: -@code{SELECT ... INTO TABLE ...}. MySQL supports instead the +MySQL Server doesn't yet support the Oracle SQL extension: +@code{SELECT ... INTO TABLE ...}. MySQL Server supports instead the ANSI SQL syntax @code{INSERT INTO ... SELECT ...}, which is basically the same thing. @xref{INSERT SELECT}. @@ -2977,20 +2988,20 @@ TABLE ... SELECT}. @cindex @code{BDB} tables @cindex @code{ACID} -MySQL supports transactions with the @code{InnoDB} and @code{BDB} +MySQL Server supports transactions with the @code{InnoDB} and @code{BDB} @code{Transactional table handlers}. @xref{Table types}. @code{InnoDB} provides @code{ACID} compliancy. -However, the non-transactional table types in MySQL such as +However, the non-transactional table types in MySQL Server such as @code{MyISAM} follow another paradigm for data integrity called ``@code{Atomic Operations}.'' Atomic operations often offer equal or even better integrity with much better performance. -With MySQL supporting both paradigms, the user is able to decide if +With MySQL Server supporting both paradigms, the user is able to decide if they need the speed of atomic operations or if they need to use transactional features in their applications. This choice can be made on a per-table basis. -How does one use the features of MySQL to maintain rigorous integrity +How does one use the features of MySQL Server to maintain rigorous integrity and how do these features compare with the transactional paradigm? @enumerate @@ -3003,7 +3014,7 @@ corrupting activities are not committed to the database; the server is given the opportunity to do an automatic rollback and your database is saved. -MySQL, in almost all cases, allows you to resolve potential problems +MySQL Server, in almost all cases, allows you to resolve potential problems by including simple checks before updates and by running simple scripts that check the databases for inconsistencies and automatically repair or warn if such an inconsistency occurs. Note that just by using the @@ -3025,7 +3036,7 @@ time-lap is where they could lose data. No system is 100% secure, only transactional databases, is reported to sometimes lose data in such situations. -To be safe with MySQL, whether using transactional tables or not, you +To be safe with MySQL Server, whether using transactional tables or not, you only need to have backups and have the update logging turned on. With this you can recover from any situation that you could with any other transactional database. It is, of course, always good to have @@ -3040,7 +3051,7 @@ familiar with transactions, do consider the speed benefit that non-transactional tables can offer, on the order of three to five times the speed of the fastest and most optimally tuned transactional tables. -In situations where integrity is of highest importance, MySQL offers +In situations where integrity is of highest importance, MySQL Server offers transaction-level or better reliability and integrity even for non-transactional tables. If you lock tables with @code{LOCK TABLES}, all updates will stall @@ -3056,7 +3067,7 @@ for the insert to complete. @xref{INSERT DELAYED}. means that you can be sure that while each specific update is running, no other user can interfere with it, and there will never be an automatic rollback (which can happen with transactional tables if you -are not very careful). MySQL also guarantees that there will not be +are not very careful). MySQL Server also guarantees that there will not be any dirty reads. Following are some techniques for working with non-transactional tables: @@ -3152,7 +3163,7 @@ UPDATE tbl_name SET row_flag=1 WHERE id=ID; MySQL returns 1 for the number of affected rows if the row was found and @code{row_flag} wasn't already 1 in the original row. -You can think of it as MySQL changed the above query to: +You can think of it as MySQL Server changed the above query to: @example UPDATE tbl_name SET row_flag=1 WHERE id=ID and row_flag <> 1; @@ -3181,7 +3192,7 @@ deletes the corresponding customer from a customer table when all his transactions are deleted. The planned update language will be able to handle stored procedures. -Our aim is to have stored procedures implemented in MySQL 4.1. +Our aim is to have stored procedures implemented in MySQL Server 4.1. We are also looking at triggers. @@ -3202,8 +3213,8 @@ SELECT * from table1,table2 where table1.id = table2.id; @xref{JOIN, , @code{JOIN}}. @xref{example-Foreign keys}. -In MySQL 3.23.44 and up, @code{InnoDB} tables supports checking of -foreign key constraints. @xref{InnoDB}. For other table types, MySQL +In MySQL Server 3.23.44 and up, @code{InnoDB} tables supports checking of +foreign key constraints. @xref{InnoDB}. For other table types, MySQL Server does parse the @code{FOREIGN KEY} syntax in @code{CREATE TABLE} commands, but without further action being taken. @@ -3214,13 +3225,13 @@ override. @code{FOREIGN KEY} is sometimes used as a constraint check, but this check is unnecessary in practice if rows are inserted into the tables in the right order. -In MySQL, you can work around the problem of @code{ON DELETE ...} not +In MySQL Server, you can work around the problem of @code{ON DELETE ...} not being implemented by adding the appropriate @code{DELETE} statement to an application when you delete records from a table that has a foreign key. In practice this is as quick (in some cases quicker) and much more portable than using foreign keys. -In MySQL 4.0 you can use multi-table delete to delete rows from many +In MySQL Server 4.0 you can use multi-table delete to delete rows from many tables with one command. @xref{DELETE}. In the near future we will extend the @code{FOREIGN KEY} implementation @@ -3276,20 +3287,20 @@ to backup or restore individual tables. @cindex views -It is planned to implement views in MySQL around Version 4.1. +It is planned to implement views in MySQL Server around Version 4.1. Views are mostly useful for letting users access a set of relations as one table (in read-only mode). Many SQL databases don't allow one to update any rows in a view, but you have to do the updates in the separate tables. -As MySQL is mostly used in applications and on web system where +As MySQL Server is mostly used in applications and on web system where the application writer has full control on the database usage, most of our users haven't regarded views to be very important. (At least no one has been interested enough in this to be prepared to finance the implementation of views). -One doesn't need views in MySQL to restrict access to columns -as MySQL has a very sophisticated privilege system. +One doesn't need views in MySQL Server to restrict access to columns +as MySQL Server has a very sophisticated privilege system. @xref{Privilege system}. @@ -3300,11 +3311,11 @@ as MySQL has a very sophisticated privilege system. @cindex starting, comments Some other SQL databases use @samp{--} to start comments. -MySQL has @samp{#} as the start comment character. You can also use -the C comment style @code{/* this is a comment */} with MySQL. +MySQL Server has @samp{#} as the start comment character. You can also use +the C comment style @code{/* this is a comment */} with MySQL Server. @xref{Comments}. -MySQL Version 3.23.3 and above supports the @samp{--} comment style, +MySQL Server Version 3.23.3 and above supports the @samp{--} comment style, provided the comment is followed by a space. This is because this comment style has caused many problems with automatically generated SQL queries that have used something like the following code, where @@ -3319,7 +3330,7 @@ Think about what happens if the value of @code{payment} is negative? Because @code{1--1} is legal in SQL, the consequences of allowing comments to start with @samp{--} are terrible. -Using our implementation of this method of commenting in MySQL +Using our implementation of this method of commenting in MySQL Server Version 3.23.3 and up, @code{1-- This is a comment} is actually safe. Another safe feature is that the @code{mysql} command-line client @@ -3438,13 +3449,13 @@ precision, @code{IF}, and @code{ELT()} with @code{BIGINT} or @code{DOUBLE} precision and the rest with @code{DOUBLE} precision. One should try to avoid using bigger unsigned long long values than 63 bits (9223372036854775807) for anything else than bit fields! -MySQL 4.0 has better @code{BIGINT} handling than 3.23. +MySQL Server 4.0 has better @code{BIGINT} handling than 3.23. @item All string columns, except @code{BLOB} and @code{TEXT} columns, automatically have all trailing spaces removed when retrieved. For @code{CHAR} types this is okay, and may be regarded as a feature according to ANSI SQL92. The bug is -that in MySQL, @code{VARCHAR} columns are treated the same way. +that in MySQL Server, @code{VARCHAR} columns are treated the same way. @item You can only have up to 255 @code{ENUM} and @code{SET} columns in one table. @@ -3507,7 +3518,7 @@ SELECT DISTINCT band_downloads.mp3id ORDER BY band_downloads.id DESC; @end example -In the second case you may in MySQL 3.23.x get two identical rows +In the second case you may in MySQL Server 3.23.x get two identical rows in the result set (because the hidden 'id' column may differ). Note that the this only happens for queries where you don't have the @@ -3515,38 +3526,38 @@ ORDER BY columns in the result, something that is you are not allowed to do in ANSI SQL. @item -Because MySQL allows you to work with table types that don't +Because MySQL Server allows you to work with table types that don't support transactions, and thus can't @code{rollback} data, some things -behave a little differently in MySQL than in other SQL servers. -This is just to ensure that MySQL never need to do a rollback +behave a little differently in MySQL Server than in other SQL servers. +This is just to ensure that MySQL Server never need to do a rollback for a SQL command. This may be a little awkward at times as column values must be checked in the application, but this will actually give -you a nice speed increase as it allows MySQL to do some +you a nice speed increase as it allows MySQL Server to do some optimisations that otherwise would be very hard to do. -If you set a column to an incorrect value, MySQL will, instead of +If you set a column to an incorrect value, MySQL Server will, instead of doing a rollback, store the @code{best possible value} in the column: @itemize @minus @item If you try to store a value outside the range in a numerical column, -MySQL will instead store the smallest or biggest possible value in +MySQL Server will instead store the smallest or biggest possible value in the column. @item If you try to store a string that doesn't start with a number into a -numerical column, MySQL will store 0 into it. +numerical column, MySQL Server will store 0 into it. @item If you try to store @code{NULL} into a column that doesn't take -@code{NULL} values, MySQL will store 0 or @code{''} (empty +@code{NULL} values, MySQL Server will store 0 or @code{''} (empty string) in it instead. (This behavior can, however, be changed with the -DDONT_USE_DEFAULT_FIELDS compile option). @item MySQL allows you to store some wrong date values into @code{DATE} and @code{DATETIME} columns. (Like 2000-02-31 or 2000-02-00). -If the date is totally wrong, MySQL will store the special +If the date is totally wrong, MySQL Server will store the special 0000-00-00 date value in the column. @item @@ -3568,7 +3579,7 @@ Creation of a table of type @code{MERGE} doesn't check if the underlying tables are of compatible types. @item -MySQL can't yet handle @code{NaN}, @code{-Inf} and @code{Inf} +MySQL Server can't yet handle @code{NaN}, @code{-Inf} and @code{Inf} values in double. Using these will cause problems when trying to export and import data. We should as an intermediate solution change @code{NaN} to @code{NULL} (if possible) and @code{-Inf} and @code{Inf} to the @@ -3608,7 +3619,7 @@ Delayed insert handler has pending inserts to a table. @end itemize @item -Before MySQL Version 3.23.2 an @code{UPDATE} that updated a key with +Before MySQL Server Version 3.23.2 an @code{UPDATE} that updated a key with a @code{WHERE} on the same key may have failed because the key was used to search for records and the same row may have been found multiple times: @@ -3622,14 +3633,14 @@ A workaround is to use: mysql> UPDATE tbl_name SET KEY=KEY+1 WHERE KEY+0 > 100; @end example -This will work because MySQL will not use index on expressions in +This will work because MySQL Server will not use index on expressions in the @code{WHERE} clause. @item -Before MySQL Version 3.23, all numeric types where treated as fixed-point -fields. That means you had to specify how many decimals a floating-point -field shall have. All results were returned with the correct number of -decimals. +Before MySQL Server Version 3.23, all numeric types where treated as +fixed-point fields. That means you had to specify how many decimals +a floating-point field shall have. All results were returned with the +correct number of decimals. @end itemize For platform-specific bugs, see the sections about compiling and porting. @@ -3647,7 +3658,7 @@ For platform-specific bugs, see the sections about compiling and porting. * TODO unplanned:: Things we don't Have any Plans to do @end menu -This appendix lists the features that we plan to implement in MySQL. +This appendix lists the features that we plan to implement in MySQL Server. Everything in this list is approximately in the order it will be done. If you want to affect the priority order, please register a license or support us and @@ -3661,16 +3672,16 @@ 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 -We have now shifted development to MySQL Version 4.0. Most of the basic +We have now shifted development to MySQL Server 4.0. Most of the basic things we want to have in 4.0 are already done. The target is to quickly implement the rest of the following features and then shift development -to MySQL 4.1. @xref{MySQL 4.0 In A Nutshell}. +to MySQL Server 4.1. @xref{MySQL 4.0 In A Nutshell}. The news section for 4.0 includes a list of the features we have already implemented in the 4.0 tree. @xref{News-4.0.x}. This section lists features not yet implemented in the current -version of MySQL 4.0, which will however be implemented in +version of MySQL Server 4.0, which will however be implemented in later versions of MySQL 4.0. This being very volatile information, please consider this list valid only if you are reading it from the MySQL web site (@uref{http://www.mysql.com/}). @@ -3737,7 +3748,7 @@ corrupt the table. @itemize @bullet @item Subqueries. -@code{select id from t where grp in (select grp from g where u > 100)} +@code{SELECT id FROM t WHERE grp IN (SELECT grp FROM g WHERE u > 100)} @item Atomic multi-table updates, eg @code{update items,month set items.price=month.price where items.id=month.id;}; @@ -3798,7 +3809,7 @@ options like database in use, time and date... @item Link the @code{myisampack} code into the server. @item -Port of MySQL to BeOS. +Port of the MySQL code to BeOS. @item Port of the MySQL clients to LynxOS. @item @@ -4119,10 +4130,11 @@ Nothing; We aim towards full ANSI 92 / ANSI 99 compliancy. @cindex comparisons, MySQL vs. others Our users have successfully run their own benchmarks against a number -of @code{Open Source} and traditional database servers. We are aware of -tests against @code{Oracle}, @code{DB/2}, @code{Microsoft SQL Server} -and other commercial products. Due to legal reasons we are restricted -from publishing some of those benchmarks in our reference manual. +of @code{Open Source} and traditional database servers. +We are aware of tests against @code{Oracle} server, @code{DB/2} server, +@code{Microsoft SQL Server} and other commercial products. +Due to legal reasons we are restricted from publishing some of those +benchmarks in our reference manual. This section includes a comparison with @code{mSQL} for historical reasons and with @code{PostgreSQL} as it is also an Open Source @@ -4171,9 +4183,9 @@ easy.) Because these operations are so simple, it is hard to be better at them when you have a higher startup overhead. After the connection -is established, MySQL should perform much better. +is established, MySQL Server should perform much better. -On the other hand, MySQL is much faster than @code{mSQL} (and +On the other hand, MySQL Server is much faster than @code{mSQL} (and most other SQL implementations) on the following: @itemize @bullet @@ -4181,11 +4193,11 @@ most other SQL implementations) on the following: Complex @code{SELECT} operations. @item -Retrieving large results (MySQL has a better, faster, and safer +Retrieving large results (MySQL Server has a better, faster, and safer protocol). @item -Tables with variable-length strings, because MySQL has more efficient +Tables with variable-length strings, because MySQL Server has more efficient handling and can have indexes on @code{VARCHAR} columns. @item @@ -4201,7 +4213,7 @@ Handling tables with large record lengths. @code{SELECT} on large tables. @item -Handling many connections at the same time. MySQL is fully +Handling many connections at the same time. MySQL Server is fully multi-threaded. Each connection has its own thread, which means that no thread has to wait for another (unless a thread is modifying a table another thread wants to access). In @code{mSQL}, once one @@ -4214,7 +4226,7 @@ next can be served, while all the others wait again, etc. Joins. @code{mSQL} can become pathologically slow if you change the order of tables in a @code{SELECT}. In the benchmark suite, a time more than -15000 times slower than MySQL was seen. This is due to @code{mSQL}'s +15000 times slower than MySQL Server was seen. This is due to @code{mSQL}'s lack of a join optimiser to order tables in the optimal order. However, if you put the tables in exactly the right order in @code{mSQL}2 and the @code{WHERE} is simple and uses index columns, @@ -4236,7 +4248,7 @@ Using @code{TEXT} or @code{BLOB} columns. @itemize @bullet @item @code{GROUP BY} and @code{HAVING}. @code{mSQL} does not support @code{GROUP BY} at all. -MySQL supports a full @code{GROUP BY} with both @code{HAVING} and +MySQL Server supports a full @code{GROUP BY} with both @code{HAVING} and the following functions: @code{COUNT()}, @code{AVG()}, @code{MIN()}, @code{MAX()}, @code{SUM()}, and @code{STD()}. @code{COUNT(*)} is optimised to return very quickly if the @code{SELECT} retrieves from @@ -4245,7 +4257,7 @@ one table, no other columns are retrieved, and there is no arguments. @item @code{INSERT} and @code{UPDATE} with calculations. -MySQL can do calculations in an @code{INSERT} or @code{UPDATE}. +MySQL Server can do calculations in an @code{INSERT} or @code{UPDATE}. For example: @example @@ -4253,21 +4265,21 @@ mysql> UPDATE SET x=x*10+y WHERE x<20; @end example @item Aliasing. -MySQL has column aliasing. +MySQL Server has column aliasing. @item Qualifying column names. -In MySQL, if a column name is unique among the tables used in a +In MySQ ServerL, if a column name is unique among the tables used in a query, you do not have to use the full qualifier. @item @code{SELECT} with functions. -MySQL has many functions (too many to list here; see @ref{Functions}). +MySQL Server has many functions (too many to list here; see @ref{Functions}). @end itemize @item Disk Space Efficiency That is, how small can you make your tables? -MySQL has very precise types, so you can create tables that take +MySQ ServerL has very precise types, so you can create tables that take very little space. An example of a useful MySQL datatype is the @code{MEDIUMINT} that is 3 bytes long. If you have 100,000,000 records, saving even one byte per record is very important. @@ -4276,24 +4288,24 @@ records, saving even one byte per record is very important. more difficult to get small tables. @item Stability -This is harder to judge objectively. For a discussion of MySQL +This is harder to judge objectively. For a discussion of MySQL Server stability, see @ref{Stability}. We have no experience with @code{mSQL} stability, so we cannot say anything about that. @item Price -Another important issue is the license. MySQL has a +Another important issue is the license. MySQL Server has a more flexible license than @code{mSQL}, and is also less expensive than @code{mSQL}. Whichever product you choose to use, remember to at least consider paying for a license or e-mail support. @item Perl Interfaces -MySQL has basically the same interfaces to Perl as @code{mSQL} with +MySQL Server has basically the same interfaces to Perl as @code{mSQL} with some added features. @item JDBC (Java) -MySQL currently has a lot of different JDBC drivers: +MySQL Server currently has a lot of different JDBC drivers: @itemize @bullet @item @@ -4325,7 +4337,7 @@ We know that @code{mSQL} has a JDBC driver, but we have too little experience with it to compare. @item Rate of Development -MySQL has a small core team of developers, but we are quite +MySQL Server has a small core team of developers, but we are quite used to coding C and C++ very rapidly. Because threads, functions, @code{GROUP BY}, and so on are still not implemented in @code{mSQL}, it has a lot of catching up to do. To get some perspective on this, you @@ -4335,17 +4347,17 @@ compare it with the News section of the MySQL Reference Manual most rapidly. @item Utility Programs -Both @code{mSQL} and MySQL have many interesting third-party +Both @code{mSQL} and MySQL Server have many interesting third-party tools. Because it is very easy to port upward (from @code{mSQL} to -MySQL), almost all the interesting applications that are available for -@code{mSQL} are also available for MySQL. +MySQL Server), almost all the interesting applications that are available for +@code{mSQL} are also available for MySQ ServerL. -MySQL comes with a simple @code{msql2mysql} program that fixes -differences in spelling between @code{mSQL} and MySQL for the +MySQL Server comes with a simple @code{msql2mysql} program that fixes +differences in spelling between @code{mSQL} and MySQL Server for the most-used C API functions. For example, it changes instances of @code{msqlConnect()} to @code{mysql_connect()}. Converting a client program from @code{mSQL} to -MySQL usually requires only minor effort. +MySQL Server usually requires only minor effort. @end table @menu @@ -4371,7 +4383,7 @@ The conversion procedure is: @enumerate @item Run the shell script @code{msql2mysql} on the source. This requires -the @code{replace} program, which is distributed with MySQL. +the @code{replace} program, which is distributed with MySQL Server. @item Compile. @@ -4384,7 +4396,7 @@ Differences between the @code{mSQL} C API and the MySQL C API are: @itemize @bullet @item -MySQL uses a @code{MYSQL} structure as a connection type (@code{mSQL} +MySQL Server uses a @code{MYSQL} structure as a connection type (@code{mSQL} uses an @code{int}). @item @@ -4400,11 +4412,11 @@ Just add the parameter to your old @code{msql_error()} code if you are porting old code. @item -MySQL returns an error number and a text error message for all +MySQL Server returns an error number and a text error message for all errors. @code{mSQL} returns only a text error message. @item -Some incompatibilities exist as a result of MySQL supporting +Some incompatibilities exist as a result of MySQL Server supporting multiple connections to the server from the same process. @end itemize @@ -4457,7 +4469,7 @@ If a connection is idle for 8 hours, the server closes the connection. @strong{Column types} @table @code -@item MySQL +@item MySQL Server Has the following additional types (among others; @pxref{CREATE TABLE, , @code{CREATE TABLE}}): @itemize @bullet @@ -4471,7 +4483,7 @@ Has the following additional types (among others; @code{BIGINT} type for 64-bit integers. @end itemize @item -MySQL also supports +MySQL Server also supports the following additional type attributes: @itemize @bullet @item @@ -4505,7 +4517,7 @@ And @code{LIKE} works. @strong{Index Creation} @table @code -@item MySQL +@item MySQL Server Indexes may be specified at table creation time with the @code{CREATE TABLE} statement. @item mSQL @@ -4517,7 +4529,7 @@ Indexes must be created after the table has been created, with separate @strong{To Insert a Unique Identifier into a Table} @table @code -@item MySQL +@item MySQL Server Use @code{AUTO_INCREMENT} as a column type specifier. @xref{mysql_insert_id, , @code{mysql_insert_id()}}. @@ -4529,7 +4541,7 @@ Create a @code{SEQUENCE} on a table and select the @code{_seq} column. @strong{To Obtain a Unique Identifier for a Row} @table @code -@item MySQL +@item MySQL Server Add a @code{PRIMARY KEY} or @code{UNIQUE} key to the table and use this. New in Version 3.23.11: If the @code{PRIMARY} or @code{UNIQUE} key consists of only one column and this is of type integer, one can also refer to it as @@ -4543,7 +4555,7 @@ depending on many factors. @strong{To Get the Time a Column Was Last Modified} @table @code -@item MySQL +@item MySQL Server Add a @code{TIMESTAMP} column to the table. This column is automatically set to the current date and time for @code{INSERT} or @code{UPDATE} statements if you don't give the column a value or if you give it a @code{NULL} value. @@ -4556,20 +4568,20 @@ Use the @code{_timestamp} column. @strong{@code{NULL} Value Comparisons} @table @code -@item MySQL -MySQL follows +@item MySQL Server +MySQL Server follows ANSI SQL, and a comparison with @code{NULL} is always @code{NULL}. @item mSQL In @code{mSQL}, @code{NULL = NULL} is TRUE. You must change @code{=NULL} to @code{IS NULL} and @code{<>NULL} to -@code{IS NOT NULL} when porting old code from @code{mSQL} to MySQL. +@code{IS NOT NULL} when porting old code from @code{mSQL} to MySQL Server. @end table @noindent @strong{String Comparisons} @table @code -@item MySQL +@item MySQL Server Normally, string comparisons are performed in case-independent fashion with the sort order determined by the current character set (ISO-8859-1 Latin1 by default). If you don't like this, declare your columns with the @@ -4584,7 +4596,7 @@ sorting in ASCII order. @strong{Case-insensitive Searching} @table @code -@item MySQL +@item MySQL Server @code{LIKE} is a case-insensitive or case-sensitive operator, depending on the columns involved. If possible, MySQL uses indexes if the @code{LIKE} argument doesn't start with a wild-card character. @@ -4596,7 +4608,7 @@ Use @code{CLIKE}. @strong{Handling of Trailing Spaces} @table @code -@item MySQL +@item MySQL Server Strips all spaces at the end of @code{CHAR} and @code{VARCHAR} columns. Use a @code{TEXT} column if this behavior is not desired. @item mSQL @@ -4607,20 +4619,20 @@ Retains trailing space. @strong{@code{WHERE} Clauses} @table @code -@item MySQL +@item MySQL Server MySQL correctly prioritises everything (@code{AND} is evaluated -before @code{OR}). To get @code{mSQL} behavior in MySQL, use +before @code{OR}). To get @code{mSQL} behavior in MySQL Server, use parentheses (as shown in an example below). @item mSQL Evaluates everything from left to right. This means that some logical calculations with more than three arguments cannot be expressed in any way. It also means you must change some queries when you upgrade to -MySQL. You do this easily by adding parentheses. Suppose you +MySQL Server. You do this easily by adding parentheses. Suppose you have the following @code{mSQL} query: @example mysql> SELECT * FROM table WHERE a=1 AND b=2 OR a=3 AND b=4; @end example -To make MySQL evaluate this the way that @code{mSQL} would, +To make MySQL Server evaluate this the way that @code{mSQL} would, you must add parentheses: @example mysql> SELECT * FROM table WHERE (a=1 AND (b=2 OR (a=3 AND (b=4)))); @@ -4631,7 +4643,7 @@ mysql> SELECT * FROM table WHERE (a=1 AND (b=2 OR (a=3 AND (b=4)))); @strong{Access Control} @table @code -@item MySQL +@item MySQL Server Has tables to store grant (permission) options per user, host, and database. @xref{Privileges}. @item mSQL @@ -4651,17 +4663,17 @@ on making our respective database as good as possible, so we are both a serious alternative to any commercial database. The following comparison is made by us at MySQL AB. We have tried to be -as accurate and fair as possible, but because while we know MySQL througly +as accurate and fair as possible, but because while we know MySQL Server thorougly we don't have a full knowledge of all PostgreSQL features, so we may have got some things wrong. We will however correct these when they come to our attention. -We would first like to note that PostgreSQL and MySQL are both widely used +We would first like to note that PostgreSQL and MySQL Server are both widely used products, but with different design goals, even if we are both striving -towards ANSI SQL compliancy. This means that for some applications MySQL +towards ANSI SQL compliancy. This means that for some applications MySQL Server is more suited, while for others PostgreSQL is more suited. When choosing which database to use, you should first check if the database's feature set -satisfies your application. If you need raw speed, MySQL is probably your +satisfies your application. If you need raw speed, MySQL Server is probably your best choice. If you need some of the extra features that only PostgreSQL can offer, you should use @code{PostgreSQL}. @@ -4676,7 +4688,7 @@ can offer, you should use @code{PostgreSQL}. @subsubsection MySQL and PostgreSQL development strategies @cindex PostgreSQL vs. MySQL, strategies -When adding things to MySQL we take pride to do an optimal, definite +When adding things to MySQL Server we take pride to do an optimal, definite solution. The code should be so good that we shouldn't have any need to change it in the foreseeable future. We also do not like to sacrifice speed for features but instead will do our utmost to find a solution @@ -4696,7 +4708,7 @@ it makes sense to prioritise adding a lot of new features, instead of implementing them optimally, because one can always optimise things later if there arises a need for this. -Another big difference between MySQL and PostgreSQL is that +Another big difference between MySQL Server and PostgreSQL is that nearly all of the code in the MySQL server are coded by developers that are employed by MySQL AB and are still working on the server code. The exceptions are the transaction engines, and the regexp library. @@ -4728,23 +4740,23 @@ database. The above web page is however extremely useful when you want to ensure that your applications works with many different databases or when you want to convert your application from one database to another. -MySQL offers the following advantages over PostgreSQL: +MySQL Server offers the following advantages over PostgreSQL: @itemize @bullet @item -@code{MySQL} is generally much faster than PostgreSQL. +@code{MySQL} Server is generally much faster than PostgreSQL. @item MySQL has a much larger user base than PostgreSQL, therefore the code is more tested and has historically proven more stable than -PostgreSQL. MySQL is the much more used in production +PostgreSQL. MySQL Server is the much more used in production environments than PostgreSQL, mostly thanks to that MySQL AB, formerly TCX DataKonsult AB, has provided top quality commercial support -for MySQL from the day it was released, whereas until recently +for MySQL Server from the day it was released, whereas until recently PostgreSQL was unsupported. @item -MySQL works better on Windows than PostgreSQL does. MySQL runs as a +MySQL Server works better on Windows than PostgreSQL does. MySQL Server runs as a native Windows application (a service on NT/Win2000/WinXP), while PostgreSQL is run under the @code{Cygwin} emulation. We have heard that PostgreSQL is not yet that stable on Windows but we haven't @@ -4755,8 +4767,8 @@ MySQL has more APIs to other languages and is supported by more existing programs than PostgreSQL. @xref{Contrib}. @item -MySQL works on 24/7 heavy duty systems. In most circumstances -you never have to run any cleanups on MySQL. PostgreSQL doesn't +MySQL Server works on 24/7 heavy duty systems. In most circumstances +you never have to run any cleanups on MySQL Server. PostgreSQL doesn't yet support 24/7 systems because you have to run @code{VACUUM()} once in a while to reclaim space from @code{UPDATE} and @code{DELETE} commands and to perform statistics analyses that are critical to get @@ -4782,31 +4794,31 @@ Included in the MySQL distribution are two different testing suites, (@uref{http://www.mysql.com/information/crash-me.php}), as well as a benchmark suite. The test system is actively updated with code to test each new feature and almost all reproduceable bugs that have come to -our attention. We test MySQL with these on a lot of platforms before +our attention. We test MySQL Server with these on a lot of platforms before every release. These tests are more sophisticated than anything we have -seen from PostgreSQL, and they ensures that the MySQL is kept to a high +seen from PostgreSQL, and they ensures that the MySQL Server is kept to a high standard. @item -There are far more books in print about MySQL than about PostgreSQL. +There are far more books in print about MySQL Server than about PostgreSQL. O'Reilly, SAMS, Que, and New Riders are all major publishers with books about MySQL. All MySQL features are also documented in the MySQL on-line manual, because when a new feature is implemented, the MySQL developers are required to document it before it's included in the source. @item -MySQL supports more of the standard ODBC functions than @code{PostgreSQL}. +MySQL Server supports more of the standard ODBC functions than @code{PostgreSQL}. @item -MySQL has a much more sophisticated @code{ALTER TABLE}. +MySQL Server has a much more sophisticated @code{ALTER TABLE}. @item -MySQL has support for tables without transactions for applications that +MySQL Server has support for tables without transactions for applications that need all speed they can get. The tables may be memory based, @code{HEAP} tables or disk based @code{MyISAM}. @xref{Table types}. @item -MySQL has support for two different table handlers that support +MySQL Server has support for two different table handlers that support transactions, @code{InnoDB} and @code{BerkeleyDB}. Because every transaction engine performs differently under different conditions, this gives the application writer more options to find an optimal solution for @@ -4825,33 +4837,33 @@ reads. This is very useful when you are archiving things. @xref{myisampack}. @item -MySQL has internal support for fulltext search. @xref{Fulltext Search}. +MySQL Server has internal support for fulltext search. @xref{Fulltext Search}. @item You can access many databases from the same connection (depending of course on your privileges). @item -MySQL is coded from the start to be multi-threaded while PostgreSQL uses +MySQL Server is coded from the start to be multi-threaded while PostgreSQL uses processes. Context switching and access to common storage areas is much -faster between threads than between separate processes, this gives MySQL +faster between threads than between separate processes, this gives MySQL Server a big speed advantage in multi-user applications and also makes it easier -for MySQL to take full advantage of symmetric multiprocessor (SMP) systems. +for MySQL Server to take full advantage of symmetric multiprocessor (SMP) systems. @item -MySQL has a much more sophisticated privilege system than PostgreSQL. +MySQL Server has a much more sophisticated privilege system than PostgreSQL. While PostgreSQL only supports @code{INSERT}, @code{SELECT}, and -@code{UPDATE/DELETE} grants per user on a database or a table, MySQL allows +@code{UPDATE/DELETE} grants per user on a database or a table, MySQL Server allows you to define a full set of different privileges on database, table and -column level. MySQL also allows you to specify the privilege on host and +column level. MySQL Server also allows you to specify the privilege on host and user combinations. @xref{GRANT}. @item -MySQL supports a compressed client/server protocol which improves +MySQL Server supports a compressed client/server protocol which improves performance over slow links. @item -MySQL employs a ``table handler'' concept, and is the only relational +MySQL Server employs a ``table handler'' concept, and is the only relational database we know of built around this concept. This allows different low-level table types to be called from the SQL engine, and each table type can be optimised for different performance characteristics. @@ -4868,19 +4880,19 @@ of a data file happens, usually from a hardware failure. It allows a majority of the data to be recovered. @item -Upgrading MySQL is painless. When you are upgrading MySQL, you don't need +Upgrading MySQL Server is painless. When you are upgrading MySQL Server, you don't need to dump/restore your data, as you have to do with most PostgreSQL upgrades. @end itemize -Drawbacks with MySQL compared to PostgreSQL: +Drawbacks with MySQL Server compared to PostgreSQL: @itemize @bullet @item -The transaction support in MySQL is not yet as well tested as PostgreSQL's +The transaction support in MySQL Server is not yet as well tested as PostgreSQL's system. @item -Because MySQL uses threads, which are not yet flawless on many OSes, one +Because MySQL Server uses threads, which are not yet flawless on many OSes, one must either use binaries from @uref{http://www.mysql.com/downloads/}, or carefully follow our instructions on @uref{http://www.mysql.com/doc/I/n/Installing_source.html} to get an @@ -4896,22 +4908,22 @@ application. If not, one can always switch the trouble table to use one of the transactional table types. @xref{Table locking}. @item -With UDF (user defined functions) one can extend MySQL with both normal +With UDF (user defined functions) one can extend MySQL Server with both normal SQL functions and aggregates, but this is not yet as easy or as flexible as in PostgreSQL. @xref{Adding functions}. @item -Updates that run over multiple tables is harder to do in MySQL. -This will, however, be fixed in MySQL 4.0 with multi-table @code{UPDATE} -and in MySQL 4.1 with subselects. -In MySQL 4.0 one can use multi-table deletes to delete from many tables +Updates that run over multiple tables is harder to do in MySQL Server. +This will, however, be fixed in MySQL Server 4.0 with multi-table @code{UPDATE} +and in MySQL Server 4.1 with subselects. +In MySQL Server 4.0 one can use multi-table deletes to delete from many tables at the same time. @xref{DELETE}. @end itemize -PostgreSQL currently offers the following advantages over MySQL: +PostgreSQL currently offers the following advantages over MySQL Server: Note that because we know the MySQL road map, we have included in the -following table the version when MySQL should support this feature. +following table the version when MySQL Server should support this feature. Unfortunately we couldn't do this for previous comparison, because we don't know the PostgreSQL roadmap. @@ -4941,7 +4953,7 @@ Standard usage in PostgreSQL is closer to ANSI SQL in some cases. One can speed up PostgreSQL by coding things as stored procedures. @item -For geographical data, R-TREES makes PostgreSQL better than MySQL. +For geographical data, R-TREES makes PostgreSQL better than MySQL Server. @item The PostgreSQL optimiser can do some optimisation that the current MySQL @@ -4956,7 +4968,7 @@ databases. PostgreSQL has a bigger team of developers that contribute to the server. @end itemize -Drawbacks with PostgreSQL compared to MySQL: +Drawbacks with PostgreSQL compared to MySQL Server: @itemize @bullet @item @@ -4979,7 +4991,7 @@ in this section. @cindex PostgreSQL vs. MySQL, benchmarks The only open source benchmark that we know of that can be used to -benchmark MySQL and PostgreSQL (and other databases) is our own. It can +benchmark MySQL Server and PostgreSQL (and other databases) is our own. It can be found at @uref{http://www.mysql.com/information/benchmarks.html}. We have many times asked the PostgreSQL developers and some PostgreSQL @@ -5023,12 +5035,12 @@ database is very good at and not testing anything that the database is not good at. If one, after doing this, summarises the result with as a single figure, things are even easier. -This would be like us measuring the speed of MySQL compared to PostgreSQL +This would be like us measuring the speed of MySQL Server compared to PostgreSQL by looking at the summary time of the MySQL benchmarks on our web page. -Based on this MySQL would be more than 40 times faster than PostgreSQL, +Based on this MySQL Server would be more than 40 times faster than PostgreSQL, something that is of course not true. We could make things even worse by just taking the test where PostgreSQL performs worst and claim that -MySQL is more than 2000 times faster than PostgreSQL. +MySQL Server is more than 2000 times faster than PostgreSQL. The case is that MySQL does a lot of optimisations that PostgreSQL doesn't do. This is of course also true the other way around. An SQL @@ -5043,7 +5055,7 @@ give you a notion about things to avoid and what you may have to do in other ways. We know of two benchmark tests that claims that PostgreSQL performs better -than MySQL. These both where multi-user tests, a test that we here at +than MySQL Server. These both where multi-user tests, a test that we here at MySQL AB haven't had time to write and include in the benchmark suite, mainly because it's a big task to do this in a manner that is fair against all databases. @@ -5101,7 +5113,7 @@ database itself. @item When running the database against Oracle and MS-SQL (Great Bridge has -indirectly indicated that the databases they used in the test), they +indirectly indicated the databases they used in the test), they didn't use the native protocol but instead ODBC. Anyone that has ever used Oracle knows that all real application uses the native interface instead of ODBC. Doing a test through ODBC and claiming that the results @@ -5123,7 +5135,7 @@ doing this. @item After the first test, we contacted Great Bridge and mentioned to them -some of the obvious mistakes they had done with MySQL: +some of the obvious mistakes they had done with MySQL Server: @itemize @minus @item @@ -5136,12 +5148,12 @@ Running on a Linux system that wasn't optimised for threads Using an old MySQL version when there was a recommended newer one available @item -Not starting MySQL with the right options for heavy multi-user use (the -default installation of MySQL is tuned for minimal resource use). +Not starting MySQL Server with the right options for heavy multi-user use (the +default installation of MySQL Server is tuned for minimal resource use). @end itemize Great Bridge did run a new test, with our optimised ODBC driver and with -better startup options for MySQL, but refused to either use our updated +better startup options for MySQL Server, but refused to either use our updated glibc library or our standard binary (used by 80% of our users), which was statically linked with a fixed glibc library. @@ -5161,9 +5173,9 @@ published a comparison on PHPbuilder When we became aware of the comparison, we phoned Tim Perdue about this because there were a lot of strange things in his results. For example, -he claimed that MySQL had a problem with five users in his tests, when we +he claimed that MySQL Server had a problem with five users in his tests, when we know that there are users with similar machines as his that are using -MySQL with 2000 simultaneous connections doing 400 queries per second. +MySQL Server with 2000 simultaneous connections doing 400 queries per second. (In this case the limit was the web bandwidth, not the database.) It sounded like he was using a Linux kernel that either had some @@ -5185,10 +5197,10 @@ He has not done that yet. Because of this we can't put any trust in this benchmark either :( Over time things also changes and the above benchmarks are not that -relevant anymore. MySQL now have a couple of different table handlers +relevant anymore. MySQL Server now has a couple of different table handlers with different speed/concurrency tradeoffs. @xref{Table types}. It would be interesting to see how the above tests would run with the -different transactional table types in MySQL. PostgreSQL has of course +different transactional table types in MySQL Server. PostgreSQL has of course also got new features since the test was made. As the above test are not publicly available there is no way for us to know how the database would preform in the same tests today. @@ -5197,7 +5209,8 @@ database would preform in the same tests today. Conclusion: The only benchmarks that exist today that anyone can download and run -against MySQL and PostgreSQL is the MySQL benchmarks. We here at MySQL +against MySQL Server and PostgreSQL is the MySQL benchmarks. +We here at MySQL AB believe that open source databases should be tested with open source tools! This is the only way to ensure that no one does tests that nobody can reproduce and use this to claim that a database is better than another. @@ -5208,7 +5221,7 @@ The thing we find strange is that every test we have seen about PostgreSQL, that is impossible to reproduce, claims that PostgreSQL is better in most cases while our tests, which anyone can reproduce, clearly shows otherwise. With this we don't want to say that PostgreSQL -isn't good at many things (it is!) or that it isn't faster than MySQL +isn't good at many things (it is!) or that it isn't faster than MySQL Server under certain conditions. We would just like to see a fair test where they are very good so that we could get some friendly competition going! @@ -8050,6 +8063,10 @@ version 4.0; @itemize @bullet @item +To use @code{MATCH ... AGAINST (... IN BOOLEAN MODE)} with your tables, +you need to rebuild them with @code{ALTER TABLE table_name TYPE=MyISAM}, +@strong{even} if they are of @code{MyISAM} type. +@item @code{LOCATE()} and @code{INSTR()} are case sensitive if neither argument is a binary string. @item @@ -9925,11 +9942,16 @@ appropriate class for this user in the password file if you are not using the default (use: chpass mysqld-user-name). @xref{safe_mysqld, , @code{safe_mysqld}}. +If you have a lot of memory you should consider rebuilding +the kernel to allow MySQL to take more than 512M of RAM. +Take a look at @code{option MAXDSIZ} in the LINT config +file for more info. + If you get problems with the current date in MySQL, setting the @code{TZ} variable will probably help. @xref{Environment variables}. To get a secure and stable system you should only use FreeBSD kernels -that are marked @code{-STABLE}. +that are marked @code{-RELEASE}. @node NetBSD, OpenBSD, FreeBSD, BSD Notes @@ -10200,7 +10222,7 @@ because it can't compile @code{.S} (assembler) files. The following configure line should work: @example -CFLAGS="-DHPUX -I/opt/dce/include" CXXFLAGS="-DHPUX -I/opt/dce/include -felide-constructors -fno-exceptions -fno-rtti" CXX=gcc ./configure --with-pthread --with-named-thread-libs='-ldce' --prefix=/usr/local/mysql --disable-shared +CFLAGS="-DHPUX -I/opt/dce/include -fpic" CXXFLAGS="-DHPUX -I/opt/dce/include -felide-constructors -fno-exceptions -fno-rtti" CXX=gcc ./configure --with-pthread --with-named-thread-libs='-ldce' --prefix=/usr/local/mysql --disable-shared @end example If you are compiling @code{gcc} 2.95 yourself, you should NOT link it with @@ -19100,7 +19122,8 @@ queries that require MySQL to scan whole tables or you have joins that don't use keys properly. @item If @code{Threads_created} is big, you may want to increase the -@code{thread_cache_size} variable. +@code{thread_cache_size} variable. The cache hit rate can be calculated +with @code{Threads_created}/@code{Connections}. @item If @code{Created_tmp_disk_tables} is big, you may want to increase the @code{tmp_table_size} variable to get the temporary tables memory based @@ -22089,8 +22112,12 @@ is @code{localhost}. Lock all tables before starting the dump. The tables are locked with @code{READ LOCAL} to allow concurrent inserts in the case of @code{MyISAM} tables. +@item -K, --no-disable-keys. +@code{/*!40000 ALTER TABLE tb_name DISABLE KEYS */;} and +@code{/*!40000 ALTER TABLE tb_name ENABLE KEYS */;} +will not be put in the output. @item -n, --no-create-db -'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;' will not be put in the +@code{CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;} will not be put in the output. The above line will be added otherwise, if --databases or --all-databases option was given. @item -t, --no-create-info @@ -22139,6 +22166,10 @@ Verbose mode. Print out more information on what the program does. Print version information and exit. @item -w, --where='where-condition' Dump only selected records. Note that quotes are mandatory: +@item -X, --xml +Dumps a database as well formed XML +@item -x, --first-slave +Locks all tables across all databases. @example "--where=user='jimf'" "-wuserid>1" "-wuserid<1" @@ -22678,10 +22709,13 @@ file is written in the data directory. If you supply an extension to @code{--log-bin=filename.extension}, the extension will be silenty removed. -To the binary log filename @code{mysqld} will append an extension that is a -number that is incremented each time you execute @code{mysqladmin -refresh}, execute @code{mysqladmin flush-logs}, execute the @code{FLUSH LOGS} -statement or restart the server. +To the binary log filename @code{mysqld} will append an extension that +is a number that is incremented each time you execute @code{mysqladmin +refresh}, execute @code{mysqladmin flush-logs}, execute the @code{FLUSH +LOGS} statement or restart the server. A new binary log will also +automaticly be created when it reaches @code{max_bin_log_size}. You can +delete all not active binary log files with the @code{RESET MASTER} +command. @xref{RESET}. You can use the following options to @code{mysqld} to affect what is logged to the binary log: @@ -34021,8 +34055,8 @@ or ROW_FORMAT= @{ default | dynamic | fixed | compressed @} or RAID_TYPE= @{1 | STRIPED | RAID0 @} RAID_CHUNKS=# RAID_CHUNKSIZE=# or UNION = (table_name,[table_name...]) or INSERT_METHOD= @{NO | FIRST | LAST @} -or DATA DIRECTORY="directory" -or INDEX DIRECTORY="directory" +or DATA DIRECTORY="absolute path to directory" +or INDEX DIRECTORY="absolute path to directory" select_statement: [IGNORE | REPLACE] SELECT ... (Some legal select statement) @@ -34563,15 +34597,6 @@ options, MySQL simply renames the files that correspond to the table @xref{RENAME TABLE,, @code{RENAME TABLE}}. @item -Since @strong{MySQL 4.0} the above feature can be activated explicitly. -@code{ALTER TABLE ... DISABLE KEYS} makes MySQL to stop updating -non-unique indexes for @code{MyISAM} table. -@code{ALTER TABLE ... ENABLE KEYS} then should be used to recreate missing -indexes. As MySQL does it with special algorithm which is much -faster then inserting keys one by one, disabling keys could give a -considerable speedup on bulk inserts. - -@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. @@ -34671,6 +34696,15 @@ 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 +Since @strong{MySQL 4.0} the above feature can be activated explicitly. +@code{ALTER TABLE ... DISABLE KEYS} makes MySQL to stop updating +non-unique indexes for @code{MyISAM} table. +@code{ALTER TABLE ... ENABLE KEYS} then should be used to recreate missing +indexes. As MySQL does it with special algorithm which is much +faster then inserting keys one by one, disabling keys could give a +considerable speedup on bulk inserts. + +@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 @@ -35522,11 +35556,11 @@ dynamic content. Following are some performance data for the query cache (We got these by running the MySQL benchmark suite on a Linux Alpha -2x500 MHz with 2GB RAM and a 64MB query cache). +2x500 MHz with 2GB RAM and a 64MB query cache): @itemize @bullet @item -If want to disable the query cache code set @code{query_cache_size=0}. +If you want to disable the query cache code set @code{query_cache_size=0}. By disabling the query cache code there is no noticeable overhead. @item If all of the queries you're preforming are simple (such as selecting a @@ -35570,6 +35604,10 @@ In addition, a query may be seen as different if for instance one client is using a new communication protocol format or another character set than another client. +Queries that uses different databases, uses different protocol versions +or the uses different default character sets are considered different +queries and cached separately. + The cache does work for @code{SELECT CALC_ROWS ...} and @code{SELECT FOUND_ROWS() ...} type queries because the number of found rows is also stored in the cache. @@ -35577,7 +35615,7 @@ found rows is also stored in the cache. If a table changes (@code{INSERT}, @code{UPDATE}, @code{DELETE}, @code{TRUNCATE}, @code{ALTER} or @code{DROP TABLE|DATABASE}), then all cached queries that used this table (possibly through a -MRG_MyISAM table!) become invalid and are removed from the cache. +@code{MRG_MyISAM} table!) become invalid and are removed from the cache. Currently all @code{InnoDB} tables are invalidated on @code{COMMIT}, in the future this will be changed so only tables changed in the @@ -35608,8 +35646,12 @@ of the form @code{SELECT * FROM AUTOINCREMENT_FIELD IS NULL} However, @code{FOUND ROWS()} will return the correct value, even if the preceding query was fetched from the cache. -Queries that don't use any tables are not cached. +Queries that don't use any tables or if the user has a column privilege for +any of the involved tables are not cached. +Before a query is fetched from the query cache, MySQL will check that +the user has SELECT privilege to all the involved databases and +tables. If this is not the case, the cached result will not be used. @node Query Cache Configuration, Query Cache in SELECT, Query Cache How, Query Cache @subsection Query Cache Configuration @@ -35694,18 +35736,30 @@ You can monitor query cache performance in @code{SHOW STATUS}: @item @code{Qcache_inserts} @tab Number of queries added to the cache. @item @code{Qcache_hits} - @tab Number of cache hits + @tab Number of cache hits. @item @code{Qcache_not_cached} @tab Number of non-cached queries - (not cachable, or due to SQL_QUERY_CACHE_TYPE) + (not cachable, or due to @code{SQL_QUERY_CACHE_TYPE}). @item @code{Qcache_free_memory} @tab Amount of free memory for query cache. +@item @code{Qcache_total_blocks} + @tab Total number of blocks in query cache. +@item @code{Qcache_free_blocks} + @tab Number of free memory blocks in query cache. @end multitable -Please note: Total number of queries = @code{Qcache_inserts} + @code{Qcache_hits} + @code{Qcache_not_cached}. +The query cache uses variable length blocks, so @code{Qcache_total_blocks} +and @code{Qcache_free_blocks} may indicate query cache memory fragmentation. +After @code{FLUSH QUERY CACHE} only a single (big) free block remains. + +Note: Every query needs a minimum of two blocks (one for the query text +and one or more for the query results). Also, every table that is used +by a query needs one block, but if two or more queries use same table +only one block needs to be allocated. + @node Table types, Clients, Reference, Top @chapter MySQL Table Types @@ -46532,12 +46586,12 @@ variables. @cindex OLEDB @item OLEDB @itemize @bullet -@item @uref{http://www.mysql.com/Downloads/Win32/MyOLEDB.exe} -OLEDB handler for MySQL. By SWsoft. +@item @uref{http://www.mysql.com/Downloads/Win32/MyOLEDB3.exe} +MyOLEDB 3.0 installation package from SWSoft. +@item @uref{http://www.mysql.com/Downloads/Win32/mysql-oledb-3.0.0.zip} +Source for MyOLEDB 3.0. @item @uref{http://www.mysql.com/Downloads/Win32/MySamples.zip} -Examples and documentation for MyOLEDB. By SWsoft. -@item @uref{http://www.mysql.com/Downloads/Win32/Myoledb.zip} -Source for MyOLEDB. By SWsoft. +Examples and documentation for MyOLEDB. @item @uref{http://www.mysql.com/Downloads/Win32/MyOLEDB.chm} Help files for MyOLEDB. @item @uref{http://www.mysql.com/Downloads/Win32/libmyodbc.zip} @@ -47291,13 +47345,14 @@ helped to make MySQL what it is today. @appendixsec Developers at MySQL AB These are the developers that are or have been employed by @code{MySQL AB} -to work on @code{MySQL}, roughly in the order they started to work with us. -Following each developer is a small list of the tasks that the developer is -responsible for, or the accomplishments they have made. +to work on the @code{MySQL} database software, roughly in the order they +started to work with us. Following each developer is a small list of the +tasks that the developer is responsible for, or the accomplishments they +have made. @table @asis @item Michael (Monty) Widenius -Has written the following parts of MySQL: +Has written the following parts of the MySQL database software: @itemize @bullet @item All the main code in @code{mysqld}. @@ -47316,7 +47371,7 @@ The @code{replace} program (take a look at it, it's @strong{COOL}!). @item @strong{MyODBC}, the ODBC driver for Windows95. @item -Fixing bugs in MIT-pthreads to get it to work for MySQL. And +Fixing bugs in MIT-pthreads to get it to work for MySQL Server. And also Unireg, a curses-based application tool with many utilities. @item Porting of @code{mSQL} tools like @code{msqlperl}, @code{DBD}/@code{DBI}, and @@ -47518,16 +47573,16 @@ Win32 port with Borland compiler. @code{mysqlshutdown.exe} and For the effort to make a shareware SQL database. At TcX, the predecessor of MySQL AB, we started with @code{mSQL}, but found that it couldn't satisfy our purposes so instead we wrote a SQL interface to our -application builder Unireg. @code{mysqladmin} and @code{mysql} ar - programs that were largely influenced by their @code{mSQL} counterparts. +application builder Unireg. @code{mysqladmin} and @code{mysql} client are +programs that were largely influenced by their @code{mSQL} counterparts. We have put a lot of effort into making the MySQL syntax a superset of @code{mSQL}. Many of the API's ideas are borrowed from @code{mSQL} to -make it easy to port free @code{mSQL} programs to MySQL. -MySQL doesn't contain any code from @code{mSQL}. +make it easy to port free @code{mSQL} programs to the MySQL API. +The MySQL software doesn't contain any code from @code{mSQL}. Two files in the distribution (@file{client/insert_test.c} and @file{client/select_test.c}) are based on the corresponding (non-copyrighted) files in the @code{mSQL} distribution, but are modified as examples showing -the changes necessary to convert code from @code{mSQL} to MySQL. +the changes necessary to convert code from @code{mSQL} to MySQL Server. (@code{mSQL} is copyrighted David J. Hughes.) @item Fred Fish For his excellent C debugging and trace library. Monty has made a number @@ -47558,9 +47613,9 @@ For the @code{DBD} (Perl) interface. @item Tim Bunce Author of @code{mysqlhotcopy}. @item Andreas Koenig @email{a.koenig@@mind.de} -For the Perl interface to MySQL. +For the Perl interface for MySQL Server. @item Eugene Chan @email{eugene@@acenet.com.sg} -For porting PHP to MySQL. +For porting PHP for MySQL Server. @item Michael J. Miller Jr. @email{mke@@terrapin.turbolift.com} For the first MySQL manual. And a lot of spelling/language fixes for the FAQ (that turned into the MySQL manual a long @@ -47579,7 +47634,7 @@ software developed by Chris Provenzano, the University of California, Berkeley, and contributors. We are currently using version 1_60_beta6 patched by Monty (see @file{mit-pthreads/Changes-mysql}). @item Xavier Leroy @email{Xavier.Leroy@@inria.fr} -The author of LinuxThreads (used by MySQL on Linux). +The author of LinuxThreads (used by the MySQL Server on Linux). @item Zarko Mocnik @email{zarko.mocnik@@dem.si} Sorting for Slovenian language and the @file{cset.tar.gz} module that makes it easier to add other character sets. @@ -47591,15 +47646,14 @@ answering on the MySQL mailing list. @item Yves Carlier @email{Yves.Carlier@@rug.ac.be} @code{mysqlaccess}, a program to show the access rights for a user. @item Rhys Jones @email{rhys@@wales.com} (And GWE Technologies Limited) -For the JDBC, a module to extract data from MySQL with a Java -client. +For the JDBC, a module to extract data from a MySQL Database with a Java client. @item Dr Xiaokun Kelvin ZHU @email{X.Zhu@@brad.ac.uk} Further development of the JDBC driver and other MySQL-related Java tools. @item James Cooper @email{pixel@@organic.com} For setting up a searchable mailing list archive at his site. @item Rick Mehalick @email{Rick_Mehalick@@i-o.com} -For @code{xmysql}, a graphical X client for MySQL. +For @code{xmysql}, a graphical X client for MySQL Server. @item Doug Sisk @email{sisk@@wix.com} For providing RPM packages of MySQL for RedHat Linux. @item Diemand Alexander V. @email{axeld@@vial.ethz.ch} @@ -47665,11 +47719,11 @@ Help to set up InstallShield for MySQL-Win32. @item Jethro Wright III @email{jetman@@li.net} The @file{libmysql.dll} library. @item James Pereria @email{jpereira@@iafrica.com} -Mysqlmanager, a Win32 GUI tool for administrating MySQL. +Mysqlmanager, a Win32 GUI tool for administrating MySQL Server. @item Curt Sampson @email{cjs@@portal.ca} Porting of MIT-pthreads to NetBSD/Alpha and NetBSD 1.3/i386. @item Antony T. Curtis @email{antony.curtis@@olcs.net} -Porting of MySQL to OS/2. +Porting of the MySQL Database software to OS/2. @item Martin Ramsch @email{m.ramsch@@computer.org} Examples in the MySQL Tutorial. @item Steve Harvey @@ -47812,6 +47866,15 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}. @itemize @bullet @item +Fixed bug when @code{HANDLER} was used with some unsupported table type. +@item +@code{mysqldump} now puts @code{ALTER TABLE table_name DISABLE KEYS} and +@code{ALTER TABLE table_name DISABLE KEYS} in the sql dump. +@item +Added @code{mysql_fix_extensions} script +@item +Fixed stack overrun problem @code{LOAD DATA FROM MASTER} on OSF1. +@item Fixed shutdown problem on HPUX. @item Added functions @code{des_encrypt()} and @code{des_decrypt()}. @@ -48081,6 +48144,12 @@ not yet 100% confident in this code. @appendixsubsec Changes in release 3.23.47 @itemize @bullet @item +InnoDB now supports @code{NULL} in keys. +@item +Fixed shutdown problem on HPUX. (Introduced in 3.23.46) +@item +Added 'DO expression' command. +@item Fixed core-dump bug in replication when using SELECT RELEASE_LOCK(); @item Added new statement DO expression,[expression]. diff --git a/client/mysql.cc b/client/mysql.cc index 27fc096ccaf..2f040a0596f 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1717,7 +1717,6 @@ print_table_data_xml(MYSQL_RES *result) (void) tee_fputs("\n <row>\n", PAGER); for (uint i=0; i < mysql_num_fields(result); i++) { - char *data; ulong *lengths=mysql_fetch_lengths(result); tee_fprintf(PAGER, "\t<%s>", (fields[i].name ? (fields[i].name[0] ? fields[i].name : diff --git a/client/mysqldump.c b/client/mysqldump.c index 229a4e79748..083f7a02d6f 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -72,8 +72,8 @@ static my_bool verbose=0,tFlag=0,cFlag=0,dFlag=0,quick=0, extended_insert = 0, lock_tables=0,ignore_errors=0,flush_logs=0,replace=0, ignore=0,opt_drop=0,opt_keywords=0,opt_lock=0,opt_compress=0, opt_delayed=0,create_options=0,opt_quoted=0,opt_databases=0, - opt_alldbs=0,opt_create_db=0,opt_first_slave=0, - opt_autocommit=0, opt_master_data, opt_xml=0; + opt_alldbs=0,opt_create_db=0,opt_first_slave=0, + opt_autocommit=0,opt_master_data,opt_disable_keys=0,opt_xml=0; static MYSQL mysql_connection,*sock=0; static char insert_pat[12 * 1024],*opt_password=0,*current_user=0, *current_host=0,*path=0,*fields_terminated=0, @@ -90,55 +90,56 @@ FILE *md_result_file; static struct option long_options[] = { {"all-databases", no_argument, 0, 'A'}, - {"all", no_argument, 0, 'a'}, - {"add-drop-table", no_argument, 0, OPT_DROP}, - {"add-locks", no_argument, 0, OPT_LOCKS}, - {"allow-keywords", no_argument, 0, OPT_KEYWORDS}, + {"all", no_argument, 0, 'a'}, + {"add-drop-table", no_argument, 0, OPT_DROP}, + {"add-locks", no_argument, 0, OPT_LOCKS}, + {"allow-keywords", no_argument, 0, OPT_KEYWORDS}, {"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR}, - {"complete-insert", no_argument, 0, 'c'}, - {"compress", no_argument, 0, 'C'}, + {"complete-insert", no_argument, 0, 'c'}, + {"compress", no_argument, 0, 'C'}, {"databases", no_argument, 0, 'B'}, - {"debug", optional_argument, 0, '#'}, + {"debug", optional_argument, 0, '#'}, {"default-character-set", required_argument, 0, OPT_DEFAULT_CHARSET}, - {"delayed-insert", no_argument, 0, OPT_DELAYED}, - {"extended-insert", no_argument, 0, 'e'}, + {"delayed-insert", no_argument, 0, OPT_DELAYED}, + {"extended-insert", no_argument, 0, 'e'}, {"fields-terminated-by", required_argument, 0, (int) OPT_FTB}, {"fields-enclosed-by", required_argument, 0, (int) OPT_ENC}, {"fields-optionally-enclosed-by", required_argument, 0, (int) OPT_O_ENC}, {"fields-escaped-by", required_argument, 0, (int) OPT_ESC}, {"first-slave", no_argument, 0, 'x'}, {"flush-logs", no_argument, 0, 'F'}, - {"force", no_argument, 0, 'f'}, - {"help", no_argument, 0, '?'}, - {"host", required_argument, 0, 'h'}, + {"force", no_argument, 0, 'f'}, + {"help", no_argument, 0, '?'}, + {"host", required_argument, 0, 'h'}, {"lines-terminated-by", required_argument, 0, (int) OPT_LTB}, - {"lock-tables", no_argument, 0, 'l'}, - {"master-data", no_argument, 0, OPT_MASTER_DATA}, + {"lock-tables", no_argument, 0, 'l'}, + {"master-data", no_argument, 0, OPT_MASTER_DATA}, {"no-autocommit", no_argument, 0, OPT_AUTOCOMMIT}, {"no-create-db", no_argument, 0, 'n'}, - {"no-create-info", no_argument, 0, 't'}, - {"no-data", no_argument, 0, 'd'}, - {"opt", no_argument, 0, OPT_OPTIMIZE}, - {"password", optional_argument, 0, 'p'}, + {"no-create-info", no_argument, 0, 't'}, + {"no-data", no_argument, 0, 'd'}, + {"no-disable-keys", no_argument, 0, 'K'}, + {"opt", no_argument, 0, OPT_OPTIMIZE}, + {"password", optional_argument, 0, 'p'}, #ifdef __WIN__ - {"pipe", no_argument, 0, 'W'}, + {"pipe", no_argument, 0, 'W'}, #endif - {"port", required_argument, 0, 'P'}, - {"quick", no_argument, 0, 'q'}, + {"port", required_argument, 0, 'P'}, + {"quick", no_argument, 0, 'q'}, {"quote-names", no_argument, 0, 'Q'}, {"result-file", required_argument, 0, 'r'}, {"set-variable", required_argument, 0, 'O'}, - {"socket", required_argument, 0, 'S'}, + {"socket", required_argument, 0, 'S'}, #include "sslopt-longopts.h" - {"tab", required_argument, 0, 'T'}, + {"tab", required_argument, 0, 'T'}, {"tables", no_argument, 0, OPT_TABLES}, #ifndef DONT_ALLOW_USER_CHANGE - {"user", required_argument, 0, 'u'}, + {"user", required_argument, 0, 'u'}, #endif - {"verbose", no_argument, 0, 'v'}, - {"version", no_argument, 0, 'V'}, - {"where", required_argument, 0, 'w'}, - {"xml", no_argument, 0, 'X'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"where", required_argument, 0, 'w'}, + {"xml", no_argument, 0, 'X'}, {0, 0, 0, 0} }; @@ -214,6 +215,9 @@ static void usage(void) puts("\ -l, --lock-tables Lock all tables for read.\n\ --no-autocommit Wrap tables with autocommit/commit statements.\n\ + -K, --no-disable-keys '/*!40000 ALTER TABLE tb_name DISABLE KEYS */;\n\ + and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */;\n\ + will not be put in the output.\n\ -n, --no-create-db 'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;'\n\ will not be put in the output. The above line will\n\ be added otherwise, if --databases or\n\ @@ -227,7 +231,7 @@ puts("\ -p, --password[=...] Password to use when connecting to server.\n\ If password is not given it's solicited on the tty.\n"); #ifdef __WIN__ - puts("-W, --pipe Use named pipes to connect to server"); + puts("-W, --pipe Use named pipes to connect to server"); #endif printf("\ -P, --port=... Port number to use for connection.\n\ @@ -305,7 +309,7 @@ static int get_options(int *argc,char ***argv) load_defaults("my",load_default_groups,argc,argv); set_all_changeable_vars(md_changeable_vars); while ((c=getopt_long(*argc,*argv, - "#::p::h:u:O:P:r:S:T:EBaAcCdefFlnqtvVw:?IxX", + "#::p::h:u:O:P:r:S:T:EBaAcCdefFKlnqtvVw:?IxX", long_options, &option_index)) != EOF) { switch(c) { @@ -341,6 +345,9 @@ static int get_options(int *argc,char ***argv) my_free(current_host,MYF(MY_ALLOW_ZERO_PTR)); current_host=my_strdup(optarg,MYF(MY_WME)); break; + case 'K': + opt_disable_keys=1; + break; case 'n': opt_create_db = 1; break; @@ -408,7 +415,7 @@ static int get_options(int *argc,char ***argv) case 'w': where=optarg; break; - case 'X': opt_xml = 1; break; + case 'X': opt_xml = 1; opt_disable_keys=1; break; case 'x': opt_first_slave=1; break; @@ -618,9 +625,9 @@ static uint getTableStructure(char *table, char* db) MYSQL_ROW row; my_bool init=0; uint numFields; - char *strpos, *table_name; + char *strpos, *table_name; const char *delayed; - char name_buff[NAME_LEN+3],table_buff[NAME_LEN+3]; + char name_buff[NAME_LEN+3],table_buff[NAME_LEN+3]; FILE *sql_file = md_result_file; DBUG_ENTER("getTableStructure"); @@ -643,7 +650,7 @@ static uint getTableStructure(char *table, char* db) if (mysql_query(sock, buff)) { fprintf(stderr, "%s: Can't get CREATE TABLE for table '%s' (%s)\n", - my_progname, table, mysql_error(sock)); + my_progname, table, mysql_error(sock)); safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } @@ -653,7 +660,7 @@ static uint getTableStructure(char *table, char* db) char filename[FN_REFLEN], tmp_path[FN_REFLEN]; convert_dirname(tmp_path,path,NullS); sql_file= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4), - O_WRONLY, MYF(MY_WME)); + O_WRONLY, MYF(MY_WME)); if (!sql_file) /* If file couldn't be opened */ { safe_exit(EX_MYSQLERR); @@ -677,7 +684,7 @@ static uint getTableStructure(char *table, char* db) if (mysql_query(sock,insert_pat) || !(tableRes=mysql_store_result(sock))) { fprintf(stderr, "%s: Can't get info about table: '%s'\nerror: %s\n", - my_progname, table, mysql_error(sock)); + my_progname, table, mysql_error(sock)); safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } @@ -883,6 +890,8 @@ static uint getTableStructure(char *table, char* db) fputs(";\n", sql_file); } } + if (!opt_disable_keys) + fprintf(sql_file,"\n/*!40000 ALTER TABLE %s DISABLE KEYS */;\n",table_name); if (cFlag) { strpos=strmov(strpos,") VALUES "); @@ -982,7 +991,7 @@ static void dumpTable(uint numFields, char *table) end= add_load_option(end, lines_terminated, " LINES TERMINATED BY"); *end= '\0'; - sprintf(buff," FROM %s",table); + sprintf(buff," FROM %s",quote_name(table,table_buff)); end= strmov(end,buff); if (where) end= strxmov(end, " WHERE ",where,NullS); @@ -1113,7 +1122,7 @@ static void dumpTable(uint numFields, char *table) if (row[i]) { if (!IS_NUM_FIELD(field)) - { + { if (opt_xml) print_quoted_xml(md_result_file, field->name, row[i], lengths[i]); @@ -1173,7 +1182,7 @@ static void dumpTable(uint numFields, char *table) //XML - close table tag and supress regular output if (opt_xml) - fprintf(md_result_file, "\t</%s>\n", table); + fprintf(md_result_file, "\t</%s>\n", table); else if (extended_insert && row_break) fputs(";\n", md_result_file); /* If not empty table */ fflush(md_result_file); @@ -1189,6 +1198,9 @@ static void dumpTable(uint numFields, char *table) safe_exit(EX_CONSCHECK); return; } + if (!opt_disable_keys) + fprintf(md_result_file,"\n/*!40000 ALTER TABLE %s ENABLE KEYS */;\n", + quote_name(table,table_buff)); if (opt_lock) fputs("UNLOCK TABLES;\n", md_result_file); if (opt_autocommit) @@ -1270,7 +1282,7 @@ static int dump_databases(char **db_names) { int result=0; for ( ; *db_names ; db_names++) - { + { //XML edit - add database element if (opt_xml) fprintf(md_result_file, "<%s>\n", *db_names); @@ -1466,8 +1478,8 @@ int main(int argc, char **argv) { my_printf_error(0, "Error: Couldn't execute 'SHOW MASTER STATUS': %s", MYF(0), mysql_error(sock)); - } - else + } + else { row = mysql_fetch_row(master); if(row[0] && row[1]) { diff --git a/client/mysqltest.c b/client/mysqltest.c index 9d98f25eb7b..762589b0374 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -1248,7 +1248,8 @@ int close_connection(struct st_query* q) } -/* this one now is a hack - we may want to improve in in the +/* + This one now is a hack - we may want to improve in in the future to handle quotes. For now we assume that anything that is not a comma, a space or ) belongs to the argument. space is a chopper, comma or ) are delimiters/terminators @@ -1291,8 +1292,7 @@ int safe_connect(MYSQL* con, const char* host, const char* user, int i; for (i = 0; i < MAX_CON_TRIES; ++i) { - if(mysql_real_connect(con, host,user, pass, - db, port, sock, 0)) + if (mysql_real_connect(con, host,user, pass, db, port, sock, 0)) { con_error = 0; break; @@ -1365,6 +1365,9 @@ int do_connect(struct st_query* q) con_sock=fn_format(buff, con_sock, TMPDIR, "",0); if (!con_db[0]) con_db=db; + /* Special database to allow one to connect without a database name */ + if (!strcmp(con_db,"*NO-ONE*")) + con_db=0; if ((con_error = safe_connect(&next_con->mysql, con_host, con_user, con_pass, con_db, con_port, con_sock ? con_sock: 0))) diff --git a/include/my_pthread.h b/include/my_pthread.h index e6cd039c80e..4ca42339897 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -448,8 +448,10 @@ struct hostent *my_gethostbyname_r(const char *name, #if defined(HPUX) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS) #define pthread_cond_timedwait(a,b,c) my_pthread_cond_timedwait((a),(b),(c)) +#define pthread_mutex_trylock(a) my_pthread_mutex_trylock((a)) int my_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *abstime); +int my_pthread_mutex_trylock(pthread_mutex_t *mutex); #endif /* safe_mutex adds checking to mutex for easier debugging */ diff --git a/include/raid.h b/include/raid.h index 7655fbe09f7..4a988760157 100644 --- a/include/raid.h +++ b/include/raid.h @@ -22,8 +22,10 @@ #define RAID_DEFAULT_CHUNKS 4 #define RAID_DEFAULT_CHUNKSIZE 256*1024 /* 256kB */ -extern const char *raid_type_string[]; +C_MODE_START #define my_raid_type(raid_type) raid_type_string[(int)(raid_type)] +extern const char *raid_type_string[]; +C_MODE_END #if defined(USE_RAID) && !defined(DONT_USE_RAID) diff --git a/include/thr_alarm.h b/include/thr_alarm.h index 48fad54444e..5caf552718c 100644 --- a/include/thr_alarm.h +++ b/include/thr_alarm.h @@ -38,24 +38,23 @@ extern "C" { #define THR_SERVER_ALARM SIGALRM #endif -#if defined(DONT_USE_THR_ALARM) +#if defined(DONT_USE_THR_ALARM) || !defined(THREAD) #define USE_ALARM_THREAD #undef USE_ONE_SIGNAL_HAND -typedef struct st_thr_alarm_entry -{ - uint crono; -} thr_alarm_entry; +typedef my_bool thr_alarm_t; +typedef my_bool ALARM; -#define thr_alarm_init(A) (A)->crono=0 -#define thr_alarm_in_use(A) (A)->crono +#define thr_alarm_init(A) (*(A))=0 +#define thr_alarm_in_use(A) (*(A) != 0) +#define thr_end_alarm(A) +#define thr_alarm(A,B,C) ((*(A)=1)-1) +/* The following should maybe be (*(A)) */ +#define thr_got_alarm(A) 0 #define init_thr_alarm(A) #define thr_alarm_kill(A) #define end_thr_alarm() -#define thr_alarm(A,B) (((A)->crono=1)-1) -#define thr_got_alarm(A) (A)->crono -#define thr_end_alarm(A) #else #if defined(__WIN__) diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c index 1734cfadfff..f83a49d01a6 100644 --- a/innobase/log/log0recv.c +++ b/innobase/log/log0recv.c @@ -564,8 +564,15 @@ recv_parse_or_apply_log_rec_body( } else if (type <= MLOG_WRITE_STRING) { new_ptr = mlog_parse_string(ptr, end_ptr, page); } else { - new_ptr = NULL; /* Eliminate compiler warning */ - ut_error; + new_ptr = NULL; + + fprintf(stderr, + "InnoDB: WARNING: the log file may have been corrupt and it\n" + "InnoDB: is possible that the log scan did not proceed\n" + "InnoDB: far enough in recovery. Please run CHECK TABLE\n" + "InnoDB: on your InnoDB tables to check that they are ok!\n" + "InnoDB: Corrupt log record type %lu\n", + (ulint)type); } ut_ad(!page || new_ptr); @@ -1316,9 +1323,29 @@ recv_parse_log_rec( new_ptr = mlog_parse_initial_log_record(ptr, end_ptr, type, space, page_no); + + /* If the operating system writes to the log complete 512-byte + blocks, we should not get the warnings below in recovery. + A warning means that the header and the trailer appeared ok + in a 512-byte block, but in the middle there was something wrong. + TODO: (1) add similar warnings in the case there is an incompletely + written log record which does not extend to the boundary of a + 512-byte block. (2) Add a checksum to a log block. */ + + if (!new_ptr) { + return(0); + } + /* Check that space id and page_no are sensible */ - if (!new_ptr || *space != 0 || *page_no > 0x8FFFFFFF) { + if (*space != 0 || *page_no > 0x8FFFFFFF) { + fprintf(stderr, + "InnoDB: WARNING: the log file may have been corrupt and it\n" + "InnoDB: is possible that the log scan did not proceed\n" + "InnoDB: far enough in recovery. Please run CHECK TABLE\n" + "InnoDB: on your InnoDB tables to check that they are ok!\n" + "InnoDB: Corrupt log record type %lu, space id %lu, page no %lu\n", + (ulint)(*type), *space, *page_no); return(0); } diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index c5174adee37..c3f912d5f61 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -319,6 +319,7 @@ row_ins_dupl_error_with_rec( ulint matched_fields; ulint matched_bytes; ulint n_unique; + ulint i; n_unique = dict_index_get_n_unique(index); @@ -329,12 +330,26 @@ row_ins_dupl_error_with_rec( if (matched_fields < n_unique) { - return(FALSE); + return(FALSE); + } + + /* In a unique secondary index we allow equal key values if they + contain SQL NULLs */ + + if (!(index->type & DICT_CLUSTERED)) { + + for (i = 0; i < n_unique; i++) { + if (UNIV_SQL_NULL == dfield_get_len( + dtuple_get_nth_field(entry, i))) { + + return(FALSE); + } + } } if (!rec_get_deleted_flag(rec)) { - return(TRUE); + return(TRUE); } return(FALSE); diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index a48fb400aa6..0e9a163a5b5 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -2208,56 +2208,59 @@ mysql_real_query(MYSQL *mysql, const char *query, ulong length) static int send_file_to_server(MYSQL *mysql, const char *filename) { - int fd, readcount; - char buf[IO_SIZE*15],*tmp_name; + int fd, readcount, result= -1; + uint packet_length=MY_ALIGN(mysql->net.max_packet-16,IO_SIZE); + char *buf, tmp_name[FN_REFLEN]; DBUG_ENTER("send_file_to_server"); - fn_format(buf,filename,"","",4); /* Convert to client format */ - if (!(tmp_name=my_strdup(buf,MYF(0)))) + if (!(buf=my_malloc(packet_length,MYF(0)))) { strmov(mysql->net.last_error, ER(mysql->net.last_errno=CR_OUT_OF_MEMORY)); DBUG_RETURN(-1); } + + fn_format(tmp_name,filename,"","",4); /* Convert to client format */ if ((fd = my_open(tmp_name,O_RDONLY, MYF(0))) < 0) { + my_net_write(&mysql->net,"",0); /* Server needs one packet */ + net_flush(&mysql->net); mysql->net.last_errno=EE_FILENOTFOUND; - sprintf(buf,EE(mysql->net.last_errno),tmp_name,errno); - strmake(mysql->net.last_error,buf,sizeof(mysql->net.last_error)-1); - my_net_write(&mysql->net,"",0); net_flush(&mysql->net); - my_free(tmp_name,MYF(0)); - DBUG_RETURN(-1); + my_snprintf(mysql->net.last_error,sizeof(mysql->net.last_error)-1, + EE(mysql->net.last_errno),tmp_name, errno); + goto err; } - while ((readcount = (int) my_read(fd,buf,sizeof(buf),MYF(0))) > 0) + while ((readcount = (int) my_read(fd,(byte*) buf,packet_length,MYF(0))) > 0) { if (my_net_write(&mysql->net,buf,readcount)) { + DBUG_PRINT("error",("Lost connection to MySQL server during LOAD DATA of local file")); mysql->net.last_errno=CR_SERVER_LOST; strmov(mysql->net.last_error,ER(mysql->net.last_errno)); - DBUG_PRINT("error",("Lost connection to MySQL server during LOAD DATA of local file")); - (void) my_close(fd,MYF(0)); - my_free(tmp_name,MYF(0)); - DBUG_RETURN(-1); + goto err; } } - (void) my_close(fd,MYF(0)); /* Send empty packet to mark end of file */ if (my_net_write(&mysql->net,"",0) || net_flush(&mysql->net)) { mysql->net.last_errno=CR_SERVER_LOST; - sprintf(mysql->net.last_error,ER(mysql->net.last_errno),socket_errno); - my_free(tmp_name,MYF(0)); - DBUG_RETURN(-1); + sprintf(mysql->net.last_error,ER(mysql->net.last_errno),errno); + goto err; } if (readcount < 0) { mysql->net.last_errno=EE_READ; /* the errmsg for not entire file read */ - sprintf(buf,EE(mysql->net.last_errno),tmp_name,errno); - strmake(mysql->net.last_error,buf,sizeof(mysql->net.last_error)-1); - my_free(tmp_name,MYF(0)); - DBUG_RETURN(-1); + my_snprintf(mysql->net.last_error,sizeof(mysql->net.last_error)-1, + tmp_name,errno); + goto err; } - DBUG_RETURN(0); + result=0; /* Ok */ + +err: + if (fd >= 0) + (void) my_close(fd,MYF(0)); + my_free(buf,MYF(0)); + DBUG_RETURN(result); } diff --git a/libmysql/net.c b/libmysql/net.c index 7eb4e0159a5..666c572ccee 100644 --- a/libmysql/net.c +++ b/libmysql/net.c @@ -41,68 +41,55 @@ #include <signal.h> #include <errno.h> +/* + The following handles the differences when this is linked between the + client and the server. + + This gives an error if a too big packet is found + The server can change this with the -O switch, but because the client + can't normally do this the client should have a bigger max_allowed_packet. +*/ + #ifdef MYSQL_SERVER ulong max_allowed_packet=65536; extern ulong net_read_timeout,net_write_timeout; extern uint test_flags; #else - -/* -** Give error if a too big packet is found -** The server can change this with the -O switch, but because the client -** can't normally do this the client should have a bigger max_allowed_packet. -*/ - -ulong max_allowed_packet=~0L; +ulong max_allowed_packet=16*1024*1024L; ulong net_read_timeout= NET_READ_TIMEOUT; ulong net_write_timeout= NET_WRITE_TIMEOUT; #endif -ulong net_buffer_length=8192; /* Default length. Enlarged if necessary */ -#if defined(__WIN__) || defined(MSDOS) -#undef MYSQL_SERVER /* Win32 can't handle interrupts */ +#ifdef __WIN__ +/* The following is because alarms doesn't work on windows. */ +#undef MYSQL_SERVER #endif + #ifdef MYSQL_SERVER #include "my_pthread.h" -#include "thr_alarm.h" void sql_print_error(const char *format,...); #define RETRY_COUNT mysqld_net_retry_count extern ulong mysqld_net_retry_count; -#else - -#ifdef OS2 /* avoid name conflict */ -#define thr_alarm_t thr_alarm_t_net -#define ALARM ALARM_net -#endif - -typedef my_bool thr_alarm_t; -typedef my_bool ALARM; -#define thr_alarm_init(A) (*(A))=0 -#define thr_alarm_in_use(A) (*(A) != 0) -#define thr_end_alarm(A) -#define thr_alarm(A,B,C) local_thr_alarm((A),(B),(C)) -inline int local_thr_alarm(my_bool *A,int B __attribute__((unused)),ALARM *C __attribute__((unused))) -{ - *A=1; - return 0; -} -#define thr_got_alarm(A) 0 -#define RETRY_COUNT 1 -#endif - -#ifdef MYSQL_SERVER extern ulong bytes_sent, bytes_received; extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received; + extern void query_cache_insert(NET *net, const char *packet, ulong length); #else #undef statistic_add #define statistic_add(A,B,C) -#endif +#define DONT_USE_THR_ALARM +#define RETRY_COUNT 1 +#endif /* MYSQL_SERVER */ + +#include "thr_alarm.h" #define TEST_BLOCKING 8 +#define MAX_THREE_BYTES 255L*255L*255L + +ulong net_buffer_length=8192; /* Default length. Enlarged if necessary */ + static int net_write_buff(NET *net,const char *packet,ulong len); -#define MAX_THREE_BYTES 255L*255L*255L /* Init with packet info */ @@ -335,7 +322,7 @@ net_real_write(NET *net,const char *packet,ulong len) long int length; char *pos,*end; thr_alarm_t alarmed; -#if !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) +#if defined(MYSQL_SERVER) ALARM alarm_buff; #endif uint retry_count=0; @@ -522,7 +509,7 @@ my_real_read(NET *net, ulong *complen) uint i,retry_count=0; ulong len=packet_error; thr_alarm_t alarmed; -#if (!defined(__WIN__) && !defined(__EMX__) && !defined(OS2)) || defined(MYSQL_SERVER) +#if defined(MYSQL_SERVER) ALARM alarm_buff; #endif my_bool net_blocking=vio_is_blocking(net->vio); @@ -775,7 +762,7 @@ my_net_read(NET *net) if (read_length != MAX_THREE_BYTES) /* last package */ { - multi_byte_packet= 0; // No last zero length packet + multi_byte_packet= 0; /* No last zero len packet */ break; } multi_byte_packet= NET_HEADER_SIZE; diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index b47cbf9c12d..3c8760ad7e5 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -241,7 +241,7 @@ while test $# -gt 0; do EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT $1" ;; --sleep=*) EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT $1" - SLEEP_TIME_AFTER_RESTART="$1" + SLEEP_TIME_AFTER_RESTART=`$ECHO "$1" | $SED -e "s;--sleep=;;"` ;; --mysqld=*) TMP=`$ECHO "$1" | $SED -e "s;--mysqld=;;"` @@ -347,7 +347,7 @@ fi [ -d $MYSQL_TEST_DIR/var/tmp ] || mkdir $MYSQL_TEST_DIR/var/tmp [ -d $MYSQL_TEST_DIR/var/run ] || mkdir $MYSQL_TEST_DIR/var/run -[ -z "$COLUMNS" ] && COLUMNS=80 +if test ${COLUMNS:-0} -lt 80 ; then COLUMNS=80 ; fi E=`$EXPR $COLUMNS - 8` DASH72=`$ECHO '------------------------------------------------------------------------'|$CUT -c 1-$E` @@ -547,10 +547,10 @@ mysql_install_db () { for slave_num in 1 2 ; do - $RM -rf var/slave$slave_num-data/ - mkdir -p var/slave$slave_num-data/mysql - mkdir -p var/slave$slave_num-data/test - cp var/slave-data/mysql/* var/slave$slave_num-data/mysql + $RM -rf var/slave$slave_num-data/ + mkdir -p var/slave$slave_num-data/mysql + mkdir -p var/slave$slave_num-data/test + cp var/slave-data/mysql/* var/slave$slave_num-data/mysql done return 0 } @@ -604,7 +604,8 @@ abort_if_failed() start_manager() { if [ $USE_MANAGER = 0 ] ; then - echo "Manager disabled, skipping manager start." + echo "Manager disabled, skipping manager start." + $RM -f $MYSQL_MANAGER_LOG return fi $ECHO "Starting MySQL Manager" @@ -674,9 +675,9 @@ manager_term() ident=$1 shift if [ $USE_MANAGER = 0 ] ; then - $MYSQLADMIN --no-defaults -uroot --socket=$MYSQL_TMP_DIR/$ident.sock -O \ - connect_timeout=5 -O shutdown_timeout=20 shutdown >/dev/null 2>&1 - return + $MYSQLADMIN --no-defaults -uroot --socket=$MYSQL_TMP_DIR/$ident.sock -O \ + connect_timeout=5 -O shutdown_timeout=20 shutdown >> $MYSQL_MANAGER_LOG 2>&1 + return fi $MYSQL_MANAGER_CLIENT $MANAGER_QUIET_OPT --user=$MYSQL_MANAGER_USER \ --password=$MYSQL_MANAGER_PW --port=$MYSQL_MANAGER_PORT <<EOF @@ -774,7 +775,7 @@ EOF else manager_launch master $MYSQLD $master_args fi - sleep_until_file_exists $MASTER_MYSOCK $wait_for_master + sleep_until_file_exists $MASTER_MYPID $wait_for_master wait_for_master=$SLEEP_TIME_FOR_SECOND_MASTER MASTER_RUNNING=1 } @@ -874,7 +875,7 @@ start_slave() manager_launch $slave_ident $SLAVE_MYSQLD $slave_args fi eval "SLAVE$1_RUNNING=1" - sleep_until_file_exists $slave_sock $wait_for_slave + sleep_until_file_exists $slave_pid $wait_for_slave wait_for_slave=$SLEEP_TIME_FOR_SECOND_SLAVE } @@ -902,16 +903,18 @@ stop_slave () manager_term $slave_ident if [ $? != 0 ] && [ -f $slave_pid ] then # try harder! - $ECHO "slave not cooperating with mysqladmin, will try manual kill" - kill `$CAT $slave_pid` - sleep_until_file_deleted $slave_pid - if [ -f $slave_pid ] ; then - $ECHO "slave refused to die. Sending SIGKILL" - kill -9 `$CAT $slave_pid` - $RM -f $slave_pid - else - $ECHO "slave responded to SIGTERM " - fi + $ECHO "slave not cooperating with mysqladmin, will try manual kill" + kill `$CAT $slave_pid` + sleep_until_file_deleted $slave_pid + if [ -f $slave_pid ] ; then + $ECHO "slave refused to die. Sending SIGKILL" + kill -9 `$CAT $slave_pid` + $RM -f $slave_pid + else + $ECHO "slave responded to SIGTERM " + fi + else + sleep $SLEEP_TIME_AFTER_RESTART fi eval "SLAVE$1_RUNNING=0" fi @@ -924,16 +927,18 @@ stop_master () manager_term master if [ $? != 0 ] && [ -f $MASTER_MYPID ] then # try harder! - $ECHO "master not cooperating with mysqladmin, will try manual kill" - kill `$CAT $MASTER_MYPID` - sleep_until_file_deleted $MASTER_MYPID - if [ -f $MASTER_MYPID ] ; then - $ECHO "master refused to die. Sending SIGKILL" - kill -9 `$CAT $MASTER_MYPID` - $RM -f $MASTER_MYPID - else - $ECHO "master responded to SIGTERM " - fi + $ECHO "master not cooperating with mysqladmin, will try manual kill" + kill `$CAT $MASTER_MYPID` + sleep_until_file_deleted $MASTER_MYPID + if [ -f $MASTER_MYPID ] ; then + $ECHO "master refused to die. Sending SIGKILL" + kill -9 `$CAT $MASTER_MYPID` + $RM -f $MASTER_MYPID + else + $ECHO "master responded to SIGTERM " + fi + else + sleep $SLEEP_TIME_AFTER_RESTART fi MASTER_RUNNING=0 fi diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result index 7c1b7c5b60d..178c3a8cb4f 100644 --- a/mysql-test/r/drop.result +++ b/mysql-test/r/drop.result @@ -12,37 +12,37 @@ drop table t1; select * from t1; n 1 -drop database if exists foo; -create database foo; -drop database if exists foo; -create database foo; -create table foo.foo (n int); -insert into foo.foo values (4); -select * from foo.foo; +drop database if exists mysqltest; +create database mysqltest; +drop database if exists mysqltest; +create database mysqltest; +create table mysqltest.mysqltest (n int); +insert into mysqltest.mysqltest values (4); +select * from mysqltest.mysqltest; n 4 -drop database if exists foo; -create database foo; -drop database foo; -drop database if exists foo; +drop database if exists mysqltest; +create database mysqltest; +drop database mysqltest; +drop database if exists mysqltest; flush tables with read lock; -create database foo; +create database mysqltest; Got one of the listed errors unlock tables; -create database foo; +create database mysqltest; show databases; Database -foo mysql +mysqltest test flush tables with read lock; -drop database foo; +drop database mysqltest; Got one of the listed errors unlock tables; -drop database foo; +drop database mysqltest; show databases; Database mysql test -drop database foo; -Can't drop database 'foo'. Database doesn't exist +drop database mysqltest; +Can't drop database 'mysqltest'. Database doesn't exist diff --git a/mysql-test/r/flush.result b/mysql-test/r/flush.result index 99d212ee49c..a7f73a6840b 100644 --- a/mysql-test/r/flush.result +++ b/mysql-test/r/flush.result @@ -11,13 +11,13 @@ drop table t2; Table 't2' was locked with a READ lock and can't be updated drop table t2; unlock tables; -drop database if exists foo; -create database foo; -create table foo.t1(n int); -insert into foo.t1 values (23); +drop database if exists mysqltest; +create database mysqltest; +create table mysqltest.t1(n int); +insert into mysqltest.t1 values (23); flush tables with read lock; - drop database foo; -select * from foo.t1; + drop database mysqltest; +select * from mysqltest.t1; n 23 unlock tables; diff --git a/mysql-test/r/grant_cache.result b/mysql-test/r/grant_cache.result new file mode 100644 index 00000000000..d236c26d71a --- /dev/null +++ b/mysql-test/r/grant_cache.result @@ -0,0 +1,153 @@ +drop table if exists test.t1,mysqltest.t1,mysqltest.t2; +reset query cache; +flush status; +create database if not exists mysqltest; +create table mysqltest.t1 (a int,b int,c int); +create table mysqltest.t2 (a int,b int,c int); +insert into mysqltest.t1 values (1,1,1),(2,2,2); +insert into mysqltest.t2 values (3,3,3); +create table test.t1 (a char (10)); +insert into test.t1 values ("test.t1"); +select * from t1; +a +test.t1 +select * from t1; +a b c +1 1 1 +2 2 2 +select a from t1; +a +1 +2 +select c from t1; +c +1 +2 +select * from t2; +a b c +3 3 3 +select * from mysqltest.t1,test.t1; +a b c a +1 1 1 test.t1 +2 2 2 test.t1 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 6 +show status like "Qcache_hits%"; +Variable_name Value +Qcache_hits 0 +grant SELECT on mysqltest.* to mysqltest_1@localhost; +grant SELECT on mysqltest.t1 to mysqltest_2@localhost; +grant SELECT on test.t1 to mysqltest_2@localhost; +grant SELECT(a) on mysqltest.t1 to mysqltest_3@localhost; +select "user1"; +user1 +user1 +select * from t1; +a b c +1 1 1 +2 2 2 +select a from t1 ; +a +1 +2 +select c from t1; +c +1 +2 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 6 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 3 +show status like "Qcache_not_cached"; +Variable_name Value +Qcache_not_cached 1 +select "user2"; +user2 +user2 +select * from t1; +a b c +1 1 1 +2 2 2 +select a from t1; +a +1 +2 +select c from t1; +c +1 +2 +select * from mysqltest.t1,test.t1; +a b c a +1 1 1 test.t1 +2 2 2 test.t1 +select * from t2; +select command denied to user: 'mysqltest_2@localhost' for table 't2' +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 6 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 7 +show status like "Qcache_not_cached"; +Variable_name Value +Qcache_not_cached 3 +select "user3"; +user3 +user3 +select * from t1; +select command denied to user: 'mysqltest_3@localhost' for column 'b' in table 't1' +select a from t1; +a +1 +2 +select c from t1; +select command denied to user: 'mysqltest_3@localhost' for column 'c' in table 't1' +select * from t2; +select command denied to user: 'mysqltest_3@localhost' for table 't2' +select mysqltest.t1.c from test.t1,mysqltest.t1; +select command denied to user: 'mysqltest_3@localhost' for column 'c' in table 't1' +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 6 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 7 +show status like "Qcache_not_cached"; +Variable_name Value +Qcache_not_cached 8 +select "user4"; +user4 +user4 +select a from t1; +No Database Selected +select * from mysqltest.t1,test.t1; +a b c a +1 1 1 test.t1 +2 2 2 test.t1 +select a from mysqltest.t1; +a +1 +2 +select a from mysqltest.t1; +a +1 +2 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 8 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 8 +show status like "Qcache_not_cached"; +Variable_name Value +Qcache_not_cached 9 +delete from mysql.user where user in ("mysqltest_1","mysqltest_2","mysqltest_3"); +delete from mysql.db where user in ("mysqltest_1","mysqltest_2","mysqltest_3"); +delete from mysql.tables_priv where user in ("mysqltest_1","mysqltest_2","mysqltest_3"); +delete from mysql.columns_priv where user in ("mysqltest_1","mysqltest_2","mysqltest_3"); +flush privileges; +drop table test.t1,mysqltest.t1,mysqltest.t2; +drop database mysqltest; diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 5d3634376d8..8664cab0b84 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -848,16 +848,16 @@ id name value uid 3 three three value 103 6 two other value 102 drop table t1; -create database test_$1; -create table test_$1.t1 (a int not null) type= innodb; -insert into test_$1.t1 values(1); -create table test_$1.t2 (a int not null) type= myisam; -insert into test_$1.t2 values(1); -create table test_$1.t3 (a int not null) type= heap; -insert into test_$1.t3 values(1); +create database mysqltest; +create table mysqltest.t1 (a int not null) type= innodb; +insert into mysqltest.t1 values(1); +create table mysqltest.t2 (a int not null) type= myisam; +insert into mysqltest.t2 values(1); +create table mysqltest.t3 (a int not null) type= heap; +insert into mysqltest.t3 values(1); commit; -drop database test_$1; -show tables from test_$1; +drop database mysqltest; +show tables from mysqltest; Got one of the listed errors create table t1 (a int not null) type= innodb; insert into t1 values(1),(2); @@ -900,8 +900,14 @@ explain select a,b,c from t1; table type possible_keys key key_len ref rows Extra t1 ALL NULL NULL NULL NULL 4 drop table t1; -create table t1 (testint int not null default 1) type=innodb; +create table t1 (t int not null default 1, key (t)) type=innodb; desc t1; Field Type Null Key Default Extra -testint int(11) 1 +t int(11) MUL 1 +handler t1 open t1; +Table handler for 't1' doesn't have this option +handler t1 read t first; +Unknown table 't1' in HANDLER +handler t1 close; +Unknown table 't1' in HANDLER drop table t1; diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index bae492b0b50..fa130deec19 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -2,7 +2,7 @@ flush query cache; flush query cache; reset query cache; flush status; -drop table if exists t1,t2,t3,t11,t21; +drop table if exists t1,t2,t3,t11,t21, mysqltest.t1; create table t1 (a int not null); insert into t1 values (1),(2),(3); select * from t1; @@ -346,19 +346,19 @@ show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 0 drop table t1,t2; -create database foo; -create table foo.t1 (i int not null auto_increment, a int, primary key (i)); -insert into foo.t1 (a) values (1); -select * from foo.t1 where i is null; +create database if not exists mysqltest; +create table mysqltest.t1 (i int not null auto_increment, a int, primary key (i)); +insert into mysqltest.t1 (a) values (1); +select * from mysqltest.t1 where i is null; i a 1 1 -select * from foo.t1; +select * from mysqltest.t1; i a 1 1 show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 1 -drop database foo; +drop database mysqltest; show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 0 @@ -375,4 +375,65 @@ set CHARACTER SET DEFAULT; show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 2 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 4 +drop table t1; +create database if not exists mysqltest; +create table mysqltest.t1 (i int not null); +create table t1 (i int not null); +insert into mysqltest.t1 (i) values (1); +insert into t1 (i) values (2); +select * from t1; +i +2 +use mysqltest; +select * from t1; +i +1 +select * from t1; +i +1 +use test; +select * from t1; +i +2 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 6 +drop database mysqltest; +drop table t1; +flush query cache; +reset query cache; +create table t1 (a int not null); +insert into t1 values (1),(2),(3); +select * from t1; +a +1 +2 +3 +select * from t1; +a +1 +2 +3 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +insert delayed into t1 values (4); +select a from t1; +a +1 +2 +3 +4 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 drop table t1; +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 diff --git a/mysql-test/t/drop.test b/mysql-test/t/drop.test index faf0a1a31b4..c92f2b1f3b9 100644 --- a/mysql-test/t/drop.test +++ b/mysql-test/t/drop.test @@ -11,33 +11,33 @@ create table t1(n int); drop table t1; select * from t1; -#now test for a bug in drop database - it is important that the name -#of the table is the same as the name of the database - in the original -#code this triggered a bug -drop database if exists foo; -create database foo; -drop database if exists foo; -create database foo; -create table foo.foo (n int); -insert into foo.foo values (4); -select * from foo.foo; -drop database if exists foo; -create database foo; -drop database foo; +# now test for a bug in drop database - it is important that the name +# of the table is the same as the name of the database - in the original +# code this triggered a bug +drop database if exists mysqltest; +create database mysqltest; +drop database if exists mysqltest; +create database mysqltest; +create table mysqltest.mysqltest (n int); +insert into mysqltest.mysqltest values (4); +select * from mysqltest.mysqltest; +drop database if exists mysqltest; +create database mysqltest; +drop database mysqltest; # test drop/create database and FLUSH TABLES WITH READ LOCK -drop database if exists foo; +drop database if exists mysqltest; flush tables with read lock; --error 1209,1223; -create database foo; +create database mysqltest; unlock tables; -create database foo; +create database mysqltest; show databases; flush tables with read lock; --error 1208,1223; -drop database foo; +drop database mysqltest; unlock tables; -drop database foo; +drop database mysqltest; show databases; --error 1008 -drop database foo; +drop database mysqltest; diff --git a/mysql-test/t/flush.test b/mysql-test/t/flush.test index 6a09b903873..38aa37caa4f 100644 --- a/mysql-test/t/flush.test +++ b/mysql-test/t/flush.test @@ -44,15 +44,15 @@ reap; #test if drop database will wait until we release the global read lock connection con1; -drop database if exists foo; -create database foo; -create table foo.t1(n int); -insert into foo.t1 values (23); +drop database if exists mysqltest; +create database mysqltest; +create table mysqltest.t1(n int); +insert into mysqltest.t1 values (23); flush tables with read lock; connection con2; -send drop database foo; +send drop database mysqltest; connection con1; -select * from foo.t1; +select * from mysqltest.t1; unlock tables; connection con2; reap; diff --git a/mysql-test/t/grant_cache-master.opt b/mysql-test/t/grant_cache-master.opt new file mode 100644 index 00000000000..cfdce628e74 --- /dev/null +++ b/mysql-test/t/grant_cache-master.opt @@ -0,0 +1 @@ +--set-variable=query_cache_size=1355776 diff --git a/mysql-test/t/grant_cache.test b/mysql-test/t/grant_cache.test new file mode 100644 index 00000000000..a6c878cc31c --- /dev/null +++ b/mysql-test/t/grant_cache.test @@ -0,0 +1,102 @@ +# +# Test grants with query cache +# +drop table if exists test.t1,mysqltest.t1,mysqltest.t2; +reset query cache; +flush status; +connect (root,localhost,root,,test,0,master.sock); +connection root; +create database if not exists mysqltest; + +create table mysqltest.t1 (a int,b int,c int); +create table mysqltest.t2 (a int,b int,c int); +insert into mysqltest.t1 values (1,1,1),(2,2,2); +insert into mysqltest.t2 values (3,3,3); +create table test.t1 (a char (10)); +insert into test.t1 values ("test.t1"); +select * from t1; +connect (root2,localhost,root,,mysqltest,0,master.sock); +connection root2; +# put queries in cache +select * from t1; +select a from t1; +select c from t1; +select * from t2; +select * from mysqltest.t1,test.t1; +show status like "Qcache_queries_in_cache"; +show status like "Qcache_hits%"; + +# Create the test users +grant SELECT on mysqltest.* to mysqltest_1@localhost; +grant SELECT on mysqltest.t1 to mysqltest_2@localhost; +grant SELECT on test.t1 to mysqltest_2@localhost; +grant SELECT(a) on mysqltest.t1 to mysqltest_3@localhost; + +# The following queries should be fetched from cache +connect (user1,localhost,mysqltest_1,,mysqltest,0,master.sock); +connection user1; +select "user1"; +select * from t1; +# The pre and end space are intentional + select a from t1 ; +select c from t1; +show status like "Qcache_queries_in_cache"; +show status like "Qcache_hits"; +show status like "Qcache_not_cached"; + +# The following queries should be fetched from cache +connect (user2,localhost,mysqltest_2,,mysqltest,0,master.sock); +connection user2; +select "user2"; +select * from t1; +select a from t1; +select c from t1; +select * from mysqltest.t1,test.t1; +--error 1142 +select * from t2; +show status like "Qcache_queries_in_cache"; +show status like "Qcache_hits"; +show status like "Qcache_not_cached"; + +# The following queries should not be fetched from cache +connect (user3,localhost,mysqltest_3,,mysqltest,0,master.sock); +connection user3; +select "user3"; +--error 1143 +select * from t1; +select a from t1; +--error 1143 +select c from t1; +--error 1142 +select * from t2; +--error 1143 +select mysqltest.t1.c from test.t1,mysqltest.t1; +show status like "Qcache_queries_in_cache"; +show status like "Qcache_hits"; +show status like "Qcache_not_cached"; + +# Connect without a database +connect (user4,localhost,mysqltest_1,,*NO-ONE*,0,master.sock); +connection user4; +select "user4"; +--error 1046 +select a from t1; +# The following query is not cached before (different database) +select * from mysqltest.t1,test.t1; +# Cache a query with 'no database' +select a from mysqltest.t1; +select a from mysqltest.t1; +show status like "Qcache_queries_in_cache"; +show status like "Qcache_hits"; +show status like "Qcache_not_cached"; + +# Cleanup + +connection root; +delete from mysql.user where user in ("mysqltest_1","mysqltest_2","mysqltest_3"); +delete from mysql.db where user in ("mysqltest_1","mysqltest_2","mysqltest_3"); +delete from mysql.tables_priv where user in ("mysqltest_1","mysqltest_2","mysqltest_3"); +delete from mysql.columns_priv where user in ("mysqltest_1","mysqltest_2","mysqltest_3"); +flush privileges; +drop table test.t1,mysqltest.t1,mysqltest.t2; +drop database mysqltest; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index 36bcad1db3c..9440886ff1e 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -518,18 +518,18 @@ drop table t1; # Test DROP DATABASE # -create database test_$1; -create table test_$1.t1 (a int not null) type= innodb; -insert into test_$1.t1 values(1); -create table test_$1.t2 (a int not null) type= myisam; -insert into test_$1.t2 values(1); -create table test_$1.t3 (a int not null) type= heap; -insert into test_$1.t3 values(1); +create database mysqltest; +create table mysqltest.t1 (a int not null) type= innodb; +insert into mysqltest.t1 values(1); +create table mysqltest.t2 (a int not null) type= myisam; +insert into mysqltest.t2 values(1); +create table mysqltest.t3 (a int not null) type= heap; +insert into mysqltest.t3 values(1); commit; -drop database test_$1; +drop database mysqltest; # Don't check error message --error 12,12 -show tables from test_$1; +show tables from mysqltest; # # Test truncate table @@ -565,9 +565,15 @@ explain select a,b,c from t1; drop table t1; # -# Check describe +# Check describe & handler # -create table t1 (testint int not null default 1) type=innodb; +create table t1 (t int not null default 1, key (t)) type=innodb; desc t1; +--error 1031 +handler t1 open t1; +--error 1109 +handler t1 read t first; +--error 1109 +handler t1 close; drop table t1; diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index 5f67ea2b59a..8a577d0be05 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -8,7 +8,7 @@ flush query cache; # This crashed in some versions flush query cache; # This crashed in some versions reset query cache; flush status; -drop table if exists t1,t2,t3,t11,t21; +drop table if exists t1,t2,t3,t11,t21, mysqltest.t1; # # First simple test @@ -235,18 +235,19 @@ drop table t1,t2; # # noncachable ODBC work around (and prepare cache for drop database) # -create database foo; -create table foo.t1 (i int not null auto_increment, a int, primary key (i)); -insert into foo.t1 (a) values (1); -select * from foo.t1 where i is null; +create database if not exists mysqltest; +create table mysqltest.t1 (i int not null auto_increment, a int, primary key (i)); +insert into mysqltest.t1 (a) values (1); +select * from mysqltest.t1 where i is null; # # drop db # -select * from foo.t1; +select * from mysqltest.t1; show status like "Qcache_queries_in_cache"; -drop database foo; +drop database mysqltest; show status like "Qcache_queries_in_cache"; + # # Charset convertion (cp1251_koi8 always present) # @@ -257,9 +258,50 @@ set CHARACTER SET cp1251_koi8; select * from t1; set CHARACTER SET DEFAULT; show status like "Qcache_queries_in_cache"; +show status like "Qcache_hits"; drop table t1; # The following tests can't be done as the values differen on 32 and 64 bit # machines :( #show variables like "query_cache_size"; #show status like "Qcache_free_memory"; + +# +# same tables in different db +# +create database if not exists mysqltest; +create table mysqltest.t1 (i int not null); +create table t1 (i int not null); +insert into mysqltest.t1 (i) values (1); +insert into t1 (i) values (2); + +select * from t1; +use mysqltest; +select * from t1; +select * from t1; +use test; +select * from t1; +show status like "Qcache_queries_in_cache"; +show status like "Qcache_hits"; + +drop database mysqltest; +drop table t1; + +# +# Test insert delayed +# + +flush query cache; +reset query cache; + +create table t1 (a int not null); +insert into t1 values (1),(2),(3); +select * from t1; +select * from t1; +show status like "Qcache_queries_in_cache"; +insert delayed into t1 values (4); +--sleep 5 # Wait for insert delayed to be executed. +select a from t1; +show status like "Qcache_queries_in_cache"; +drop table t1; +show status like "Qcache_queries_in_cache"; diff --git a/mysql-test/t/rpl_get_lock.test b/mysql-test/t/rpl_get_lock.test index 93f911e01d5..3fe45eecf46 100644 --- a/mysql-test/t/rpl_get_lock.test +++ b/mysql-test/t/rpl_get_lock.test @@ -6,6 +6,16 @@ dirty_close master; connection master1; select get_lock("lock",2); select release_lock("lock"); +#ignore +disable_query_log; +let $1=2000; +while ($1) +{ + do get_lock("lock",2); + do release_lock("lock"); + dec $1; +} +enable_query_log; save_master_pos; connection slave; sync_with_master; diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c index 7fc094bdb71..8834dda98e1 100644 --- a/mysys/my_bitmap.c +++ b/mysys/my_bitmap.c @@ -25,7 +25,7 @@ #include "mysys_priv.h" #include <my_bitmap.h> #include <assert.h> -#include <string.h> +#include <m_string.h> inline void bitmap_lock(MY_BITMAP* map) { diff --git a/mysys/my_pthread.c b/mysys/my_pthread.c index 161e4faaff6..37c18a32451 100644 --- a/mysys/my_pthread.c +++ b/mysys/my_pthread.c @@ -471,6 +471,8 @@ struct hostent *my_gethostbyname_r(const char *name, this has to be added here. *****************************************************************************/ +#ifdef HPUX + int my_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *abstime) { @@ -483,6 +485,18 @@ int my_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, } +int my_pthread_mutex_trylock(pthread_mutex_t *mutex) +{ + int error=pthread_mutex_trylock(mutex); + if (error == 1) /* Safety if the lib is fixed */ + return 0; /* Mutex was locked */ + if (error == -1) /* Safety if the lib is fixed */ + error=errno; + return error; +} + +#endif + /* Some help functions */ int pthread_no_free(void *not_used __attribute__((unused))) diff --git a/scripts/Makefile.am b/scripts/Makefile.am index c83a7e2315f..7ac554cda1d 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -20,6 +20,7 @@ bin_SCRIPTS = @server_scripts@ \ msql2mysql \ mysql_config \ mysql_fix_privilege_tables \ + mysql_fix_extensions \ mysql_setpermission \ mysql_zap \ mysqlaccess \ @@ -35,6 +36,7 @@ EXTRA_SCRIPTS = make_binary_distribution.sh \ msql2mysql.sh \ mysql_config.sh \ mysql_fix_privilege_tables.sh \ + mysql_fix_extensions.sh \ mysql_install_db.sh \ mysql_setpermission.sh \ mysql_zap.sh \ @@ -61,6 +63,7 @@ CLEANFILES = @server_scripts@ \ msql2mysql \ mysql_config \ mysql_fix_privilege_tables \ + mysql_fix_extensions \ mysql_setpermission \ mysql_zap \ mysqlaccess \ diff --git a/scripts/mysql_fix_extensions.sh b/scripts/mysql_fix_extensions.sh new file mode 100644 index 00000000000..fbc72406f5e --- /dev/null +++ b/scripts/mysql_fix_extensions.sh @@ -0,0 +1,16 @@ +#!@PERL@ +# This is a utility for MySQL. It is not needed by any standard part +# of MySQL. + +# Usage: mysql_fix_extentions datadir +# does not work with RAID, with InnoDB or BDB tables +# makes .frm lowercase and .MYI/MYD/ISM/ISD uppercase +# useful when datafiles are copied from windows + +die "Usage: $0 datadir\n" unless -d $ARGV[0]; + +for $a (<$ARGV[0]/*/*.*>) { $_=$a; + s/\.frm$/.frm/i; + s/\.(is[md]|my[id])$/\U$&/i; + rename ($a, $_) || warn "Cannot rename $a => $_ : $!"; +} diff --git a/sql-bench/test-wisconsin.sh b/sql-bench/test-wisconsin.sh index e7e3a0f235a..adc3e5b5aa4 100644 --- a/sql-bench/test-wisconsin.sh +++ b/sql-bench/test-wisconsin.sh @@ -242,7 +242,7 @@ sub init_data { @onek= $server->create("onek", - ["unique1 int(4) NOT NULL", + ["unique1 int(5) NOT NULL", "unique2 int(4) NOT NULL", "two int(4)", "four int(4)", diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h index ab1ead5a3e9..65116f908ac 100644 --- a/sql/ha_berkeley.h +++ b/sql/ha_berkeley.h @@ -90,7 +90,7 @@ class ha_berkeley: public handler HA_REC_NOT_IN_SEQ | HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER | HA_LONGLONG_KEYS | HA_NULL_KEY | HA_HAVE_KEY_READ_ONLY | - HA_BLOB_KEY | HA_NOT_EXACT_COUNT | HA_NO_FULLTEXT_KEY | + HA_BLOB_KEY | HA_NOT_EXACT_COUNT | HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE | HA_AUTO_PART_KEY), changed_rows(0),last_dup_key((uint) -1),version(0),using_ignore(0) diff --git a/sql/ha_heap.h b/sql/ha_heap.h index 93deedb65d2..9b041411012 100644 --- a/sql/ha_heap.h +++ b/sql/ha_heap.h @@ -35,7 +35,7 @@ class ha_heap: public handler ulong option_flag() const { return (HA_READ_RND_SAME | HA_NO_INDEX | HA_ONLY_WHOLE_INDEX | HA_WRONG_ASCII_ORDER | HA_KEYPOS_TO_RNDPOS | HA_NO_BLOBS | - HA_REC_NOT_IN_SEQ | HA_NO_FULLTEXT_KEY); } + HA_REC_NOT_IN_SEQ); } uint max_record_length() const { return HA_MAX_REC_LENGTH; } uint max_keys() const { return MAX_KEY; } uint max_key_parts() const { return MAX_REF_PARTS; } diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc index 3a71da6ba84..836a1a4331e 100644 --- a/sql/ha_innobase.cc +++ b/sql/ha_innobase.cc @@ -2961,7 +2961,8 @@ ha_innobase::records_in_range( KEY* key; dict_index_t* index; mysql_byte* key_val_buff2 = (mysql_byte*) my_malloc( - table->reclength, + table->reclength + + table->max_key_length + 100, MYF(MY_WME)); dtuple_t* range_start; dtuple_t* range_end; diff --git a/sql/ha_innobase.h b/sql/ha_innobase.h index 83e43b1d662..b1613c2503c 100644 --- a/sql/ha_innobase.h +++ b/sql/ha_innobase.h @@ -79,7 +79,7 @@ class ha_innobase: public handler HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | HA_HAVE_KEY_READ_ONLY | HA_READ_NOT_EXACT_KEY | HA_LONGLONG_KEYS | HA_NULL_KEY | - HA_NOT_EXACT_COUNT | HA_NO_FULLTEXT_KEY | + HA_NOT_EXACT_COUNT | HA_NO_WRITE_DELAYED | HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE | @@ -96,10 +96,12 @@ class ha_innobase: public handler uint max_record_length() const { return HA_MAX_REC_LENGTH; } uint max_keys() const { return MAX_KEY; } uint max_key_parts() const { return MAX_REF_PARTS; } - /* An InnoDB page must store >= 2 keys: - max key length is therefore set to 7000 - bytes */ - uint max_key_length() const { return 7000; } + /* An InnoDB page must store >= 2 keys; + a secondary key record must also contain the + primary key value: + max key length is therefore set to slightly + less than 1 / 4 of page size which is 16 kB */ + uint max_key_length() const { return 3500; } bool fast_key_read() { return 1;} key_map keys_to_use_for_scanning() { return ~(key_map) 0; } bool has_transactions() { return 1;} diff --git a/sql/ha_isam.h b/sql/ha_isam.h index d839a6b1141..33ca99b5063 100644 --- a/sql/ha_isam.h +++ b/sql/ha_isam.h @@ -34,7 +34,7 @@ class ha_isam: public handler HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER | HA_HAVE_KEY_READ_ONLY | HA_READ_NOT_EXACT_KEY | HA_LONGLONG_KEYS | HA_KEY_READ_WRONG_STR | HA_DUPP_POS | - HA_NOT_DELETE_WITH_CACHE | HA_NO_FULLTEXT_KEY) + HA_NOT_DELETE_WITH_CACHE) {} ~ha_isam() {} const char *table_type() const { return "ISAM"; } diff --git a/sql/ha_isammrg.h b/sql/ha_isammrg.h index 5e0eaa1b2aa..888ecf0ca37 100644 --- a/sql/ha_isammrg.h +++ b/sql/ha_isammrg.h @@ -33,7 +33,7 @@ class ha_isammrg: public handler const char *table_type() const { return "MRG_ISAM"; } const char **bas_ext() const; ulong option_flag() const { return HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS - | HA_REC_NOT_IN_SEQ | HA_NO_FULLTEXT_KEY;} + | HA_REC_NOT_IN_SEQ;} uint max_record_length() const { return HA_MAX_REC_LENGTH; } uint max_keys() const { return 0; } uint max_key_parts() const { return 0; } diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h index eba2bde7d59..7b5c959ccfa 100644 --- a/sql/ha_myisam.h +++ b/sql/ha_myisam.h @@ -45,9 +45,10 @@ class ha_myisam: public handler public: ha_myisam(TABLE *table): handler(table), file(0), int_option_flag(HA_READ_NEXT | HA_READ_PREV | HA_READ_RND_SAME | - HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER | + HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER | HA_HAVE_KEY_READ_ONLY | HA_READ_NOT_EXACT_KEY | - HA_LONGLONG_KEYS | HA_NULL_KEY | + HA_LONGLONG_KEYS | HA_NULL_KEY | + HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER | HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY), enable_activate_all_index(1) {} diff --git a/sql/ha_myisammrg.h b/sql/ha_myisammrg.h index 7d696162de0..e18c520c803 100644 --- a/sql/ha_myisammrg.h +++ b/sql/ha_myisammrg.h @@ -35,7 +35,7 @@ class ha_myisammrg: public handler ulong option_flag() const { return (HA_REC_NOT_IN_SEQ | HA_READ_NEXT | HA_READ_PREV | HA_READ_RND_SAME | - HA_HAVE_KEY_READ_ONLY | HA_NO_FULLTEXT_KEY | + HA_HAVE_KEY_READ_ONLY | HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER | HA_READ_NOT_EXACT_KEY | HA_LONGLONG_KEYS | HA_NULL_KEY | HA_BLOB_KEY); } diff --git a/sql/handler.h b/sql/handler.h index 98358c3b3e4..1e2c0074475 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -76,7 +76,8 @@ #define HA_NOT_DELETE_WITH_CACHE (HA_NOT_READ_AFTER_KEY*2) #define HA_NO_TEMP_TABLES (HA_NOT_DELETE_WITH_CACHE*2) #define HA_NO_PREFIX_CHAR_KEYS (HA_NO_TEMP_TABLES*2) -#define HA_NO_FULLTEXT_KEY (HA_NO_PREFIX_CHAR_KEYS*2) +#define HA_CAN_FULLTEXT (HA_NO_PREFIX_CHAR_KEYS*2) +#define HA_CAN_SQL_HANDLER (HA_CAN_FULLTEXT*2) /* Parameters for open() (in register form->filestat) */ /* HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED */ diff --git a/sql/log_event.cc b/sql/log_event.cc index ee975596f4b..f56837cb81a 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1539,7 +1539,8 @@ int Query_log_event::exec_event(struct st_master_info* mi) { int expected_error,actual_error = 0; init_sql_alloc(&thd->mem_root, 8192,0); - thd->db = rewrite_db((char*)db); + thd->db= rewrite_db((char*)db); + thd->db_length=strlen(thd->db); if (db_ok(thd->db, replicate_do_db, replicate_ignore_db)) { thd->query = (char*)query; @@ -1584,14 +1585,16 @@ int Query_log_event::exec_event(struct st_master_info* mi) else { // master could be inconsistent, abort and tell DBA to check/fix it - thd->db = thd->query = 0; + thd->db= thd->query= 0; + thd->db_length=0; thd->convert_set = 0; close_thread_tables(thd); free_root(&thd->mem_root,0); return 1; } } - thd->db = 0; // prevent db from being freed + thd->db= 0; // prevent db from being freed + thd->db_length=0; thd->query = 0; // just to be sure // assume no convert for next query unless set explictly thd->convert_set = 0; @@ -1612,7 +1615,7 @@ int Query_log_event::exec_event(struct st_master_info* mi) int Load_log_event::exec_event(NET* net, struct st_master_info* mi) { init_sql_alloc(&thd->mem_root, 8192,0); - thd->db = rewrite_db((char*)db); + thd->db= rewrite_db((char*)db); thd->query = 0; thd->query_error = 0; @@ -1685,7 +1688,8 @@ int Load_log_event::exec_event(NET* net, struct st_master_info* mi) } thd->net.vio = 0; - thd->db = 0;// prevent db from being freed + thd->db= 0;// prevent db from being freed + thd->db_length=0; close_thread_tables(thd); if (thd->query_error) { diff --git a/sql/mini_client.cc b/sql/mini_client.cc index 3da5edac37f..6bbbe653cdd 100644 --- a/sql/mini_client.cc +++ b/sql/mini_client.cc @@ -22,21 +22,15 @@ in case we decide to make them external at some point */ +#ifdef EMBEDDED_LIBRARY +#define net_read_timeout net_read_timeout1 +#define net_write_timeout net_write_timeout1 +#endif + #if defined(__WIN__) #include <winsock.h> -#include <odbcinst.h> -/* Disable alarms */ -typedef my_bool ALARM; -#define thr_alarm_init(A) (*(A))=0 -#define thr_alarm_in_use(A) (*(A)) -#define thr_end_alarm(A) -#define thr_alarm(A,B,C) local_thr_alarm((A),(B),(C)) -inline int local_thr_alarm(my_bool *A,int B __attribute__((unused)),ALARM *C __attribute__((unused))) -{ - *A=1; - return 0; -} -#define thr_got_alarm(A) 0 +#include <odbcinst.h> /* QQ: Is this really needed ? */ +#define DONT_USE_THR_ALARM #endif #include <my_global.h> @@ -53,12 +47,7 @@ inline int local_thr_alarm(my_bool *A,int B __attribute__((unused)),ALARM *C __a #include "mysqld_error.h" #include "errmsg.h" -#ifdef EMBEDDED_LIBRARY -#define net_read_timeout net_read_timeout1 -#define net_write_timeout net_write_timeout1 -#endif - -#if defined( OS2) && defined( MYSQL_SERVER) +#if defined( OS2) && defined(MYSQL_SERVER) #undef ER #define ER CER #endif @@ -82,18 +71,17 @@ extern "C" { // Because of SCO 3.2V4.2 #ifdef HAVE_SYS_SELECT_H #include <sys/select.h> #endif -#endif +#endif /*!defined(MSDOS) && !defined(__WIN__) */ #ifdef HAVE_SYS_UN_H # include <sys/un.h> #endif #if defined(THREAD) #include <my_pthread.h> /* because of signal() */ -#include <thr_alarm.h> #endif +#include <thr_alarm.h> #ifndef INADDR_NONE #define INADDR_NONE -1 #endif - } static void mc_free_rows(MYSQL_DATA *cur); @@ -1047,7 +1035,7 @@ int STDCALL mc_mysql_query(MYSQL *mysql, const char *query, uint length) DBUG_ENTER("mysql_real_query"); DBUG_PRINT("enter",("handle: %lx",mysql)); DBUG_PRINT("query",("Query = \"%s\"",query)); - if(!length) + if (!length) length = strlen(query); if (mc_simple_command(mysql,COM_QUERY,query,length,1)) DBUG_RETURN(-1); @@ -1056,58 +1044,62 @@ int STDCALL mc_mysql_query(MYSQL *mysql, const char *query, uint length) static int mc_send_file_to_server(MYSQL *mysql, const char *filename) { - int fd, readcount; - char buf[IO_SIZE*15],*tmp_name; + int fd, readcount, result= -1; + uint packet_length=MY_ALIGN(mysql->net.max_packet-16,IO_SIZE); + char *buf, tmp_name[FN_REFLEN]; DBUG_ENTER("send_file_to_server"); - fn_format(buf,filename,"","",4); /* Convert to client format */ - if (!(tmp_name=my_strdup(buf,MYF(0)))) + if (!(buf=my_malloc(packet_length,MYF(0)))) { strmov(mysql->net.last_error, ER(mysql->net.last_errno=CR_OUT_OF_MEMORY)); DBUG_RETURN(-1); } + + fn_format(tmp_name,filename,"","",4); /* Convert to client format */ if ((fd = my_open(tmp_name,O_RDONLY, MYF(0))) < 0) { + my_net_write(&mysql->net,"",0); // Server needs one packet + net_flush(&mysql->net); mysql->net.last_errno=EE_FILENOTFOUND; - sprintf(buf,EE(mysql->net.last_errno),tmp_name,errno); - strmake(mysql->net.last_error,buf,sizeof(mysql->net.last_error)-1); - my_net_write(&mysql->net,"",0); net_flush(&mysql->net); - my_free(tmp_name,MYF(0)); - DBUG_RETURN(-1); + my_snprintf(mysql->net.last_error,sizeof(mysql->net.last_error)-1, + EE(mysql->net.last_errno),tmp_name, errno); + goto err; } - while ((readcount = (int) my_read(fd,(byte*) buf,sizeof(buf),MYF(0))) > 0) + while ((readcount = (int) my_read(fd,(byte*) buf,packet_length,MYF(0))) > 0) { if (my_net_write(&mysql->net,buf,readcount)) { + DBUG_PRINT("error",("Lost connection to MySQL server during LOAD DATA of local file")); mysql->net.last_errno=CR_SERVER_LOST; strmov(mysql->net.last_error,ER(mysql->net.last_errno)); - DBUG_PRINT("error",("Lost connection to MySQL server during LOAD DATA of local file")); - (void) my_close(fd,MYF(0)); - my_free(tmp_name,MYF(0)); - DBUG_RETURN(-1); + goto err; } } - (void) my_close(fd,MYF(0)); /* Send empty packet to mark end of file */ if (my_net_write(&mysql->net,"",0) || net_flush(&mysql->net)) { mysql->net.last_errno=CR_SERVER_LOST; sprintf(mysql->net.last_error,ER(mysql->net.last_errno),errno); - my_free(tmp_name,MYF(0)); - DBUG_RETURN(-1); + goto err; } if (readcount < 0) { mysql->net.last_errno=EE_READ; /* the errmsg for not entire file read */ - sprintf(buf,EE(mysql->net.last_errno),tmp_name,errno); - strmake(mysql->net.last_error,buf,sizeof(mysql->net.last_error)-1); - my_free(tmp_name,MYF(0)); - DBUG_RETURN(-1); + my_snprintf(mysql->net.last_error,sizeof(mysql->net.last_error)-1, + tmp_name,errno); + goto err; } - DBUG_RETURN(0); + result=0; // Ok + +err: + if (fd >= 0) + (void) my_close(fd,MYF(0)); + my_free(buf,MYF(0)); + DBUG_RETURN(result); } + /* Get the length of next field. Change parameter to point at fieldstart */ static ulong mc_net_field_length(uchar **packet) { @@ -1187,7 +1179,7 @@ static MYSQL_DATA *mc_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, if ((pkt_len=mc_net_safe_read(mysql)) == packet_error) DBUG_RETURN(0); if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA), - MYF(MY_WME | MY_ZEROFILL)))) + MYF(MY_ZEROFILL)))) { net->last_errno=CR_OUT_OF_MEMORY; strmov(net->last_error,ER(net->last_errno)); @@ -1374,7 +1366,7 @@ MYSQL_RES * STDCALL mc_mysql_store_result(MYSQL *mysql) mysql->status=MYSQL_STATUS_READY; /* server is ready */ if (!(result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES)+ sizeof(ulong)*mysql->field_count, - MYF(MY_WME | MY_ZEROFILL)))) + MYF(MY_ZEROFILL)))) { mysql->net.last_errno=CR_OUT_OF_MEMORY; strmov(mysql->net.last_error, ER(mysql->net.last_errno)); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 27dba4d62fd..739991f55b1 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -283,8 +283,9 @@ uint cached_tables(void); void kill_mysql(void); void close_connection(NET *net,uint errcode=0,bool lock=1); bool check_access(THD *thd,uint access,const char *db=0,uint *save_priv=0, - bool no_grant=0); -bool check_table_access(THD *thd,uint want_access, TABLE_LIST *tables); + bool no_grant=0, bool no_errors=0); +bool check_table_access(THD *thd,uint want_access, TABLE_LIST *tables, + bool no_errors=0); bool check_process_priv(THD *thd=0); int mysql_backup_table(THD* thd, TABLE_LIST* table_list); @@ -435,7 +436,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables); /* sql_handler.cc */ int mysql_ha_open(THD *thd, TABLE_LIST *tables); -int mysql_ha_close(THD *thd, TABLE_LIST *tables); +int mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok=0); int mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *, List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c010a2c17f9..e4e24c5ce53 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -752,7 +752,7 @@ void clean_up(bool print_message) bitmap_free(&slave_error_mask); acl_free(1); grant_free(); - query_cache.resize(0); + query_cache.destroy(); table_cache_free(); hostname_cache_free(); item_user_lock_free(); diff --git a/sql/net_pkg.cc b/sql/net_pkg.cc index 9fb478ca664..2f26ad81bd5 100644 --- a/sql/net_pkg.cc +++ b/sql/net_pkg.cc @@ -30,6 +30,7 @@ void send_error(NET *net, uint sql_errno, const char *err) err ? err : net->last_error[0] ? net->last_error : "NULL")); + query_cache_abort(net); if (thd) thd->query_error = 1; // needed to catch query errors during replication if (!err) @@ -102,9 +103,9 @@ net_printf(NET *net, uint errcode, ...) DBUG_ENTER("net_printf"); DBUG_PRINT("enter",("message: %u",errcode)); - if(thd) thd->query_error = 1; - // if we are here, something is wrong :-) - + if (thd) + thd->query_error = 1; // if we are here, something is wrong :-) + query_cache_abort(net); // Safety va_start(args,errcode); format=ER(errcode); offset= net->return_errno ? 2 : 0; diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 7eb4e0159a5..3e4dcb75ebb 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -41,68 +41,55 @@ #include <signal.h> #include <errno.h> +/* + The following handles the differences when this is linked between the + client and the server. + + This gives an error if a too big packet is found + The server can change this with the -O switch, but because the client + can't normally do this the client should have a bigger max_allowed_packet. +*/ + #ifdef MYSQL_SERVER ulong max_allowed_packet=65536; extern ulong net_read_timeout,net_write_timeout; extern uint test_flags; #else - -/* -** Give error if a too big packet is found -** The server can change this with the -O switch, but because the client -** can't normally do this the client should have a bigger max_allowed_packet. -*/ - -ulong max_allowed_packet=~0L; +ulong max_allowed_packet=16*1024*1024L; ulong net_read_timeout= NET_READ_TIMEOUT; ulong net_write_timeout= NET_WRITE_TIMEOUT; #endif -ulong net_buffer_length=8192; /* Default length. Enlarged if necessary */ -#if defined(__WIN__) || defined(MSDOS) -#undef MYSQL_SERVER /* Win32 can't handle interrupts */ +#ifdef __WIN__ +/* The following is because alarms doesn't work on windows. */ +#undef MYSQL_SERVER #endif + #ifdef MYSQL_SERVER #include "my_pthread.h" -#include "thr_alarm.h" void sql_print_error(const char *format,...); #define RETRY_COUNT mysqld_net_retry_count extern ulong mysqld_net_retry_count; -#else - -#ifdef OS2 /* avoid name conflict */ -#define thr_alarm_t thr_alarm_t_net -#define ALARM ALARM_net -#endif - -typedef my_bool thr_alarm_t; -typedef my_bool ALARM; -#define thr_alarm_init(A) (*(A))=0 -#define thr_alarm_in_use(A) (*(A) != 0) -#define thr_end_alarm(A) -#define thr_alarm(A,B,C) local_thr_alarm((A),(B),(C)) -inline int local_thr_alarm(my_bool *A,int B __attribute__((unused)),ALARM *C __attribute__((unused))) -{ - *A=1; - return 0; -} -#define thr_got_alarm(A) 0 -#define RETRY_COUNT 1 -#endif - -#ifdef MYSQL_SERVER extern ulong bytes_sent, bytes_received; extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received; + extern void query_cache_insert(NET *net, const char *packet, ulong length); #else #undef statistic_add #define statistic_add(A,B,C) -#endif +#define DONT_USE_THR_ALARM +#define RETRY_COUNT 1 +#endif /* MYSQL_SERVER */ + +#include "thr_alarm.h" #define TEST_BLOCKING 8 +#define MAX_THREE_BYTES 255L*255L*255L + +ulong net_buffer_length=8192; /* Default length. Enlarged if necessary */ + static int net_write_buff(NET *net,const char *packet,ulong len); -#define MAX_THREE_BYTES 255L*255L*255L /* Init with packet info */ @@ -335,7 +322,7 @@ net_real_write(NET *net,const char *packet,ulong len) long int length; char *pos,*end; thr_alarm_t alarmed; -#if !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) +#if defined(MYSQL_SERVER) ALARM alarm_buff; #endif uint retry_count=0; @@ -343,7 +330,8 @@ net_real_write(NET *net,const char *packet,ulong len) DBUG_ENTER("net_real_write"); #ifdef MYSQL_SERVER - query_cache_insert(net, packet, len); + if (net->query_cache_query != 0) + query_cache_insert(net, packet, len); #endif if (net->error == 2) @@ -522,7 +510,7 @@ my_real_read(NET *net, ulong *complen) uint i,retry_count=0; ulong len=packet_error; thr_alarm_t alarmed; -#if (!defined(__WIN__) && !defined(__EMX__) && !defined(OS2)) || defined(MYSQL_SERVER) +#if defined(MYSQL_SERVER) ALARM alarm_buff; #endif my_bool net_blocking=vio_is_blocking(net->vio); @@ -775,7 +763,7 @@ my_net_read(NET *net) if (read_length != MAX_THREE_BYTES) /* last package */ { - multi_byte_packet= 0; // No last zero length packet + multi_byte_packet= 0; /* No last zero len packet */ break; } multi_byte_packet= NET_HEADER_SIZE; diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 6b15bd92ac6..edb5c28ed99 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -191,10 +191,12 @@ void init_slave_list() void end_slave_list() { - pthread_mutex_lock(&LOCK_slave_list); - hash_free(&slave_list); - pthread_mutex_unlock(&LOCK_slave_list); - pthread_mutex_destroy(&LOCK_slave_list); + /* No protection by a mutex needed as we are only called at shutdown */ + if (hash_inited(&slave_list)) + { + hash_free(&slave_list); + pthread_mutex_destroy(&LOCK_slave_list); + } } static int find_target_pos(LEX_MASTER_INFO* mi, IO_CACHE* log, char* errmsg) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 0d2568e8c5e..5da31df81ab 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -132,7 +132,8 @@ int acl_init(bool dont_read_acl_tables) thd->mysys_var=my_thread_var; thd->current_tablenr=0; thd->open_tables=0; - thd->db=my_strdup("mysql",MYF(0)); + thd->db= my_strdup("mysql",MYF(0)); + thd->db_length=5; // Safety bzero((char*) &tables,sizeof(tables)); tables[0].name=tables[0].real_name=(char*) "host"; tables[1].name=tables[1].real_name=(char*) "user"; @@ -2120,7 +2121,8 @@ int grant_init (void) thd->mysys_var=my_thread_var; thd->current_tablenr=0; thd->open_tables=0; - thd->db=my_strdup("mysql",MYF(0)); + thd->db= my_strdup("mysql",MYF(0)); + thd->db_length=5; // Safety bzero((char*) &tables,sizeof(tables)); tables[0].name=tables[0].real_name= (char*) "tables_priv"; tables[1].name=tables[1].real_name= (char*) "columns_priv"; diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 8364373730e..523e835f472 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -530,9 +530,14 @@ byte *query_cache_query_get_key(const byte *record, uint *length, } /***************************************************************************** - Functions to store things into the query cache + Functions to store things into the query cache *****************************************************************************/ +/* + Insert the packet into the query cache. + This should only be called if net->query_cache_query != 0 +*/ + void query_cache_insert(NET *net, const char *packet, ulong length) { DBUG_ENTER("query_cache_insert"); @@ -543,45 +548,41 @@ void query_cache_insert(NET *net, const char *packet, ulong length) DBUG_VOID_RETURN; #endif - // Quick check on unlocked structure - if (net->query_cache_query != 0) + STRUCT_LOCK(&query_cache.structure_guard_mutex); + Query_cache_block *query_block = ((Query_cache_block*) + net->query_cache_query); + if (query_block) { - STRUCT_LOCK(&query_cache.structure_guard_mutex); - Query_cache_block *query_block = ((Query_cache_block*) - net->query_cache_query); - if (query_block) - { - Query_cache_query *header = query_block->query(); - Query_cache_block *result = header->result(); + Query_cache_query *header = query_block->query(); + Query_cache_block *result = header->result(); - DUMP(&query_cache); - BLOCK_LOCK_WR(query_block); - DBUG_PRINT("qcache", ("insert packet %lu bytes long",length)); + DUMP(&query_cache); + BLOCK_LOCK_WR(query_block); + DBUG_PRINT("qcache", ("insert packet %lu bytes long",length)); - /* - On success STRUCT_UNLOCK(&query_cache.structure_guard_mutex) will be - done by query_cache.append_result_data if success (if not we need - query_cache.structure_guard_mutex locked to free query) - */ - if (!query_cache.append_result_data(&result, length, (gptr) packet, - query_block)) - { - query_cache.refused++; - DBUG_PRINT("warning", ("Can't append data")); - header->result(result); - DBUG_PRINT("qcache", ("free query 0x%lx", (ulong) query_block)); - // The following call will remove the lock on query_block - query_cache.free_query(query_block); - // append_result_data no success => we need unlock - STRUCT_UNLOCK(&query_cache.structure_guard_mutex); - DBUG_VOID_RETURN; - } + /* + On success STRUCT_UNLOCK(&query_cache.structure_guard_mutex) will be + done by query_cache.append_result_data if success (if not we need + query_cache.structure_guard_mutex locked to free query) + */ + if (!query_cache.append_result_data(&result, length, (gptr) packet, + query_block)) + { + query_cache.refused++; + DBUG_PRINT("warning", ("Can't append data")); header->result(result); - BLOCK_UNLOCK_WR(query_block); - } - else + DBUG_PRINT("qcache", ("free query 0x%lx", (ulong) query_block)); + // The following call will remove the lock on query_block + query_cache.free_query(query_block); + // append_result_data no success => we need unlock STRUCT_UNLOCK(&query_cache.structure_guard_mutex); + DBUG_VOID_RETURN; + } + header->result(result); + BLOCK_UNLOCK_WR(query_block); } + else + STRUCT_UNLOCK(&query_cache.structure_guard_mutex); DBUG_EXECUTE("check_querycache",query_cache.check_integrity();); DBUG_VOID_RETURN; } @@ -607,11 +608,11 @@ void query_cache_abort(NET *net) BLOCK_LOCK_WR(query_block); // The following call will remove the lock on query_block query_cache.free_query(query_block); - net->query_cache_query=0; } + net->query_cache_query=0; STRUCT_UNLOCK(&query_cache.structure_guard_mutex); + DBUG_EXECUTE("check_querycache",query_cache.check_integrity();); } - DBUG_EXECUTE("check_querycache",query_cache.check_integrity();); DBUG_VOID_RETURN; } @@ -648,7 +649,6 @@ void query_cache_end_of_result(NET *net) #endif header->found_rows(current_thd->limit_found_rows); header->result()->type = Query_cache_block::RESULT; - net->query_cache_query=0; header->writer(0); BLOCK_UNLOCK_WR(query_block); } @@ -658,8 +658,8 @@ void query_cache_end_of_result(NET *net) STRUCT_UNLOCK(&query_cache.structure_guard_mutex); } net->query_cache_query=0; + DBUG_EXECUTE("check_querycache",query_cache.check_integrity();); } - DBUG_EXECUTE("check_querycache",query_cache.check_integrity();); DBUG_VOID_RETURN; } @@ -724,6 +724,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) (Not important at this stage) */ TABLE_COUNTER_TYPE tables; + ulong tot_length; DBUG_ENTER("Query_cache::store_query"); if (query_cache_size == 0) DBUG_VOID_RETURN; @@ -739,6 +740,17 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) DBUG_VOID_RETURN; DUMP(this); + /* Key is query + database + flag */ + if (thd->db_length) + { + memcpy(thd->query+thd->query_length+1, thd->db, thd->db_length); + DBUG_PRINT("qcache", ("database : %s length %u", + thd->db, thd->db_length)); + } + else + { + DBUG_PRINT("qcache", ("No active database")); + } /* Prepare flags: most significant bit - CLIENT_LONG_FLAG, @@ -749,20 +761,19 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) flags|= (byte) thd->convert_set->number(); DBUG_ASSERT(thd->convert_set->number() < 128); } + tot_length=thd->query_length+thd->db_length+2; + thd->query[tot_length-1] = (char) flags; /* Check if another thread is processing the same query? */ - thd->query[thd->query_length] = (char) flags; Query_cache_block *competitor = (Query_cache_block *) - hash_search(&queries, (byte*) thd->query, thd->query_length+1); + hash_search(&queries, (byte*) thd->query, tot_length); DBUG_PRINT("qcache", ("competitor 0x%lx, flags %x", (ulong) competitor, flags)); if (competitor == 0) { /* Query is not in cache and no one is working with it; Store it */ - thd->query[thd->query_length] = (char) flags; Query_cache_block *query_block; - query_block= write_block_data(thd->query_length+1, - (gptr) thd->query, + query_block= write_block_data(tot_length, (gptr) thd->query, ALIGN_SIZE(sizeof(Query_cache_query)), Query_cache_block::QUERY, tables, 1); if (query_block != 0) @@ -789,7 +800,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) header->unlock_n_destroy(); free_memory_block(query_block); STRUCT_UNLOCK(&structure_guard_mutex); - DBUG_VOID_RETURN; + goto end; } double_linked_list_simple_include(query_block, &queries_blocks); inserts++; @@ -821,17 +832,29 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) statistic_increment(refused, &structure_guard_mutex); end: - thd->query[thd->query_length]= 0; // Restore end null DBUG_VOID_RETURN; } +/* + Check if the query is in the cache. If it was cached, send it + to the user. + + RESULTS + 1 Query was not cached. + 0 The query was cached and user was sent the result. + -1 The query was cached but we didn't have rights to use it. + No error is sent to the client yet. +*/ + -my_bool + +int Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) { Query_cache_query *query; Query_cache_block *first_result_block, *result_block; Query_cache_block_table *block_table, *block_table_end; + ulong tot_length; byte flags; DBUG_ENTER("Query_cache::send_result_to_client"); @@ -844,9 +867,13 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) thd->query_cache_type == 0) { - DBUG_PRINT("qcache", ("query cache disabled on not in autocommit mode")); + DBUG_PRINT("qcache", ("query cache disabled or not in autocommit mode")); goto err; } + + /* Check that we haven't forgot to reset the query cache variables */ + DBUG_ASSERT(thd->net.query_cache_query == 0); + /* We can't cache the query if we are using a temporary table because we don't know if the query is using a temporary table. @@ -856,16 +883,16 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) */ if (thd->temporary_tables != 0 || !thd->safe_to_cache_query) { - DBUG_PRINT("qcache", ("SELECT is non-cacheable")); + DBUG_PRINT("qcache", ("SELECT is non-cacheable: tmp_tables: %d safe: %d", + thd->temporary_tables, + thd->safe_to_cache_query)); goto err; } - /* Test if the query is a SELECT */ - while (*sql == ' ' || *sql == '\t') - { - sql++; - query_length--; - } + /* + Test if the query is a SELECT + (pre-space is removed in dispatch_command) + */ if (toupper(sql[0]) != 'S' || toupper(sql[1]) != 'E' || toupper(sql[2]) !='L') { @@ -876,13 +903,22 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) STRUCT_LOCK(&structure_guard_mutex); if (query_cache_size == 0) { - DBUG_PRINT("qcache", ("query cache disabled and not in autocommit mode")); - STRUCT_UNLOCK(&structure_guard_mutex); - goto err; + DBUG_PRINT("qcache", ("query cache disabled")); + goto err_unlock; } - DBUG_PRINT("qcache", (" sql %u '%s'", query_length, sql)); Query_cache_block *query_block; + tot_length=query_length+thd->db_length+2; + if (thd->db_length) + { + memcpy(sql+query_length+1, thd->db, thd->db_length); + DBUG_PRINT("qcache", ("database: '%s' length %u", + thd->db, thd->db_length)); + } + else + { + DBUG_PRINT("qcache", ("No active database")); + } /* prepare flags: Most significant bit - CLIENT_LONG_FLAG, @@ -894,20 +930,16 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) flags |= (byte) thd->convert_set->number(); DBUG_ASSERT(thd->convert_set->number() < 128); } - - sql[query_length] = (char) flags; + sql[tot_length-1] = (char) flags; query_block = (Query_cache_block *) hash_search(&queries, (byte*) sql, - query_length+1); - sql[query_length] = '\0'; - + tot_length); /* Quick abort on unlocked data */ if (query_block == 0 || query_block->query()->result() == 0 || query_block->query()->result()->type != Query_cache_block::RESULT) { - STRUCT_UNLOCK(&structure_guard_mutex); DBUG_PRINT("qcache", ("No query in query hash or no results")); - goto err; + goto err_unlock; } DBUG_PRINT("qcache", ("Query in query hash 0x%lx", (ulong)query_block)); @@ -922,7 +954,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) /* The query is probably yet processed */ DBUG_PRINT("qcache", ("query found, but no data or data incomplete")); BLOCK_UNLOCK_RD(query_block); - goto err; + goto err_unlock; } DBUG_PRINT("qcache", ("Query have result 0x%lx", (ulong) query)); @@ -937,14 +969,24 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) Query_cache_table *table = block_table->parent; table_list.db = table->db(); table_list.name = table_list.real_name = table->table(); - if (check_table_access(thd,SELECT_ACL,&table_list)) + if (check_table_access(thd,SELECT_ACL,&table_list,1)) { DBUG_PRINT("qcache", ("probably no SELECT access to %s.%s => return to normal processing", table_list.db, table_list.name)); - BLOCK_UNLOCK_RD(query_block); + refused++; // This is actually a hit STRUCT_UNLOCK(&structure_guard_mutex); - goto err; + thd->safe_to_cache_query=0; // Don't try to cache this + BLOCK_UNLOCK_RD(query_block); + DBUG_RETURN(-1); // Privilege error + } + if (table_list.grant.want_privilege) + { + DBUG_PRINT("qcache", ("Need to check column privileges for %s.%s", + table_list.db, table_list.name)); + BLOCK_UNLOCK_RD(query_block); + thd->safe_to_cache_query=0; // Don't try to cache this + goto err_unlock; // Parse query } } move_to_query_list_end(query_block); @@ -973,10 +1015,12 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) thd->limit_found_rows = query->found_rows(); BLOCK_UNLOCK_RD(query_block); - DBUG_RETURN(0); + DBUG_RETURN(1); // Result sent to client +err_unlock: + STRUCT_UNLOCK(&structure_guard_mutex); err: - DBUG_RETURN(1); + DBUG_RETURN(0); // Query was not cached } /* @@ -2284,7 +2328,7 @@ void Query_cache::double_linked_list_join(Query_cache_block *head_tail, *****************************************************************************/ /* - if query is cacheable return number tables in query + If query is cacheable return number tables in query (query without tables are not cached) */ @@ -2369,8 +2413,9 @@ void Query_cache::pack_cache() { do { + Query_cache_block *next=block->pnext; ok = move_by_type(&border, &before, &gap, block); - block = block->pnext; + block = next; } while (ok && block != first_block); if (border != 0) @@ -2449,10 +2494,21 @@ my_bool Query_cache::move_by_type(byte **border, Query_cache_block_table *nlist_root = new_block->table(0); nlist_root->n = 0; - nlist_root->next = (tnext == list_root ? nlist_root : tnext); - nlist_root->prev = (tprev == list_root ? nlist_root: tnext); - tnext->prev = nlist_root; - tprev->next = nlist_root; + if (tnext == list_root) + { + nlist_root->next = nlist_root; + nlist_root->prev = nlist_root; + } + else + { + nlist_root->next = tnext; + tnext->prev = nlist_root; + } + if (tprev != list_root) + { + nlist_root->prev = tnext; + tprev->next = nlist_root; + } for (;tnext != nlist_root; tnext=tnext->next) tnext->parent = new_block->table(); *border += len; @@ -2519,10 +2575,15 @@ my_bool Query_cache::move_by_type(byte **border, Query_cache_query *new_query= ((Query_cache_query *) new_block->data()); pthread_cond_init(&new_query->lock, NULL); pthread_mutex_init(&new_query->clients_guard,MY_MUTEX_INIT_FAST); + + /* + If someone is writing to this block, inform the writer that the block + has been moved. + */ NET *net = new_block->query()->writer(); if (net != 0) { - net->query_cache_query = (gptr) new_block; + net->query_cache_query= (gptr) new_block; } /* Fix hash to point at moved block */ hash_replace(&queries, queries.current_record, (byte*) new_block); @@ -2591,10 +2652,21 @@ void Query_cache::relink(Query_cache_block *oblock, Query_cache_block *next, Query_cache_block *prev, Query_cache_block *pnext, Query_cache_block *pprev) { - nblock->prev = (prev == oblock ? nblock : prev); //check pointer to himself - nblock->next = (next == oblock ? nblock : next); - prev->next=nblock; - next->prev=nblock; + if (prev == oblock) //check pointer to himself + { + nblock->prev = nblock; + nblock->next = nblock; + } + else + { + nblock->prev = prev; + prev->next=nblock; + } + if (next != oblock) + { + nblock->next = next; + next->prev=nblock; + } nblock->pprev = pprev; // Physical pointer to himself have only 1 free block nblock->pnext = pnext; pprev->pnext=nblock; @@ -2701,7 +2773,19 @@ uint Query_cache::filename_2_table_key (char *key, const char *path) Functions to be used when debugging ****************************************************************************/ -#ifndef DBUG_OFF +#if defined(DBUG_OFF) && !defined(USE_QUERY_CACHE_INTEGRITY_CHECK) + +void wreck(uint line, const char *message) {} +void bins_dump() {} +void cache_dump() {} +void queries_dump() {} +void tables_dump() {} +my_bool check_integrity() { return 0; } +my_bool in_list(Query_cache_block * root, Query_cache_block * point, + const char *name) { return 0;} +my_bool in_blocks(Query_cache_block * point) { return 0; } + +#else void Query_cache::wreck(uint line, const char *message) { @@ -2790,15 +2874,17 @@ void Query_cache::queries_dump() { uint len; char *str = (char*) query_cache_query_get_key((byte*) block, &len, 0); - byte flags = (byte) str[len-1]; - DBUG_PRINT("qcache", ("%u (%u,%u) %.*s",len, + len--; // Point at flags + uint flags = (uint) (uchar) str[len]; + str[len]=0; + DBUG_PRINT("qcache", ("%u (%u,%u) '%s' '%s'", ((flags & QUERY_CACHE_CLIENT_LONG_FLAG_MASK)? 1:0), (flags & QUERY_CACHE_CHARSET_CONVERT_MASK), len, - str)); + str,strend(str)+1)); DBUG_PRINT("qcache", ("-b- 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx", (ulong) block, (ulong) block->next, (ulong) block->prev, (ulong)block->pnext, (ulong)block->pprev)); - + str[len]=(char) flags; for (TABLE_COUNTER_TYPE t = 0; t < block->n_tables; t++) { Query_cache_table *table = block->table(t)->parent; diff --git a/sql/sql_cache.h b/sql/sql_cache.h index 6f8d9bb6dbf..50ae765e446 100644 --- a/sql/sql_cache.h +++ b/sql/sql_cache.h @@ -354,7 +354,7 @@ protected: Check if the query is in the cache and if this is true send the data to client. */ - my_bool send_result_to_client(THD *thd, char *query, uint query_length); + int send_result_to_client(THD *thd, char *query, uint query_length); /* Remove all queries that uses any of the listed following tables */ void invalidate(TABLE_LIST *tables_used); @@ -375,7 +375,15 @@ protected: void destroy(); -#ifndef DBUG_OFF + friend void query_cache_insert(NET *net, const char *packet, ulong length); + friend void query_cache_end_of_result(NET *net); + friend void query_cache_abort(NET *net); + + /* + The following functions are only used when debugging + We don't protect these with ifndef DEBUG_OFF to not have to recompile + everything if we want to add checks of the cache at some places. + */ void wreck(uint line, const char *message); void bins_dump(); void cache_dump(); @@ -385,10 +393,6 @@ protected: my_bool in_list(Query_cache_block * root, Query_cache_block * point, const char *name); my_bool in_blocks(Query_cache_block * point); -#endif - friend void query_cache_insert(NET *net, const char *packet, ulong length); - friend void query_cache_end_of_result(NET *net); - friend void query_cache_abort(NET *net); }; extern Query_cache query_cache; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 93db784b66d..f26b2dd6847 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -85,7 +85,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), host_or_ip="unknown ip"; locked=killed=count_cuted_fields=some_tables_deleted=no_errors=password= query_start_used=safe_to_cache_query=0; - query_length=col_access=0; + db_length=query_length=col_access=0; query_error=0; next_insert_id=last_insert_id=0; open_tables=temporary_tables=handler_tables=0; diff --git a/sql/sql_class.h b/sql/sql_class.h index 803c1df9dd9..1eac7843e96 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -288,6 +288,7 @@ public: uint current_tablenr,tmp_table,cond_count,col_access; uint server_status,open_options; uint32 query_length; + uint32 db_length; enum_tx_isolation tx_isolation, session_tx_isolation; char scramble[9]; uint8 query_cache_type; // type of query cache processing @@ -400,6 +401,13 @@ public: { return strmake_root(&mem_root,str,size); } inline char *memdup(const char *str, uint size) { return memdup_root(&mem_root,str,size); } + inline char *memdup_w_gap(const char *str, uint size, uint gap) + { + gptr ptr; + if ((ptr=alloc_root(&mem_root,size+gap))) + memcpy(ptr,str,size); + return ptr; + } }; diff --git a/sql/sql_db.cc b/sql/sql_db.cc index b476a8b1797..dd8ed634011 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -317,19 +317,19 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, bool mysql_change_db(THD *thd,const char *name) { - int length; + int length, db_length; char *dbname=my_strdup((char*) name,MYF(MY_WME)); char path[FN_REFLEN]; uint db_access; DBUG_ENTER("mysql_change_db"); - if (!dbname || !(length=stripp_sp(dbname))) + if (!dbname || !(db_length=stripp_sp(dbname))) { x_free(dbname); /* purecov: inspected */ send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } - if ((length > NAME_LEN) || check_db_name(dbname)) + if ((db_length > NAME_LEN) || check_db_name(dbname)) { net_printf(&thd->net,ER_WRONG_DB_NAME, dbname); x_free(dbname); @@ -369,6 +369,7 @@ bool mysql_change_db(THD *thd,const char *name) send_ok(&thd->net); x_free(thd->db); thd->db=dbname; + thd->db_length=db_length; thd->db_access=db_access; DBUG_RETURN(0); } diff --git a/sql/sql_do.cc b/sql/sql_do.cc index 77be253766c..70124c2d796 100644 --- a/sql/sql_do.cc +++ b/sql/sql_do.cc @@ -22,7 +22,6 @@ int mysql_do(THD *thd, List<Item> &values) { - int error; List_iterator<Item> li(values); Item *value; DBUG_ENTER("mysql_do"); diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 6b3295a819c..f7effdc67e6 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -43,7 +43,7 @@ thd->open_tables=thd->handler_tables; \ thd->handler_tables=tmp; } -static TABLE **find_table_ptr_by_name(THD *thd, const char *db, +static TABLE **find_table_ptr_by_name(THD *thd, const char *db, const char *table_name); int mysql_ha_open(THD *thd, TABLE_LIST *tables) @@ -54,11 +54,19 @@ int mysql_ha_open(THD *thd, TABLE_LIST *tables) if (err) return -1; + // there can be only one table in *tables + if (!(tables->table->file->option_flag() & HA_CAN_SQL_HANDLER)) + { + my_printf_error(ER_ILLEGAL_HA,ER(ER_ILLEGAL_HA),MYF(0), tables->name); + mysql_ha_close(thd, tables,1); + return -1; + } + send_ok(&thd->net); return 0; } -int mysql_ha_close(THD *thd, TABLE_LIST *tables) +int mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok) { TABLE **ptr=find_table_ptr_by_name(thd, tables->db, tables->name); @@ -68,12 +76,18 @@ int mysql_ha_close(THD *thd, TABLE_LIST *tables) close_thread_table(thd, ptr); VOID(pthread_mutex_unlock(&LOCK_open)); } - - send_ok(&thd->net); + else + { + my_printf_error(ER_UNKNOWN_TABLE,ER(ER_UNKNOWN_TABLE),MYF(0), + tables->name,"HANDLER"); + return -1; + } + if (!dont_send_ok) + send_ok(&thd->net); return 0; } -static enum enum_ha_read_modes rkey_to_rnext[]= +static enum enum_ha_read_modes rkey_to_rnext[]= { RNEXT, RNEXT, RPREV, RNEXT, RPREV, RNEXT, RPREV }; int mysql_ha_read(THD *thd, TABLE_LIST *tables, @@ -166,7 +180,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, if (!(key= (byte*) sql_calloc(ALIGN_SIZE(key_len)))) { send_error(&thd->net,ER_OUTOFMEMORY); - goto err; + goto err; } key_copy(key, table, keyno, key_len); err=table->file->index_read(table->record[0], @@ -176,7 +190,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, } default: send_error(&thd->net,ER_ILLEGAL_HA); - goto err; + goto err; } if (err) @@ -191,7 +205,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, goto ok; } if (cond) - { + { err=err; if(!cond->val_int()) continue; @@ -234,7 +248,7 @@ err: **************************************************************************/ /* Note: this function differs from find_locked_table() because we're looking - here for alias, not real table name + here for alias, not real table name */ static TABLE **find_table_ptr_by_name(THD *thd, const char *db, const char *table_name) @@ -244,7 +258,7 @@ static TABLE **find_table_ptr_by_name(THD *thd, const char *db, if (!db || ! *db) db= thd->db ? thd->db : ""; - dblen=strlen(db)+1; + dblen=strlen(db)+1; ptr=&(thd->handler_tables); for (TABLE *table=*ptr; table ; table=*ptr) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 526bd86bb58..06a1818b50d 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1227,6 +1227,7 @@ bool delayed_insert::handle_inserts(void) sql_print_error("%s",thd.net.last_error); goto err; } + query_cache.invalidate(table); if (thr_reschedule_write_lock(*thd.lock->locks)) { /* This should never happen */ @@ -1251,6 +1252,7 @@ bool delayed_insert::handle_inserts(void) sql_print_error("%s",thd.net.last_error); goto err; } + query_cache.invalidate(table); pthread_mutex_lock(&mutex); DBUG_RETURN(0); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 851c07265b0..3662aa301e2 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -127,6 +127,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, { NET *net= &thd->net; thd->db=0; + thd->db_length=0; if (!(thd->user = my_strdup(user, MYF(0)))) { @@ -632,7 +633,8 @@ pthread_handler_decl(handle_bootstrap,arg) buff[length]=0; thd->current_tablenr=0; thd->query_length=length; - thd->query= thd->memdup(buff,length+1); + thd->query= thd->memdup_w_gap(buff, length+1, thd->db_length+1); + thd->query[length] = '\0'; thd->query_id=query_id++; mysql_parse(thd,thd->query,length); close_thread_tables(thd); // Free tables @@ -807,6 +809,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, /* Save user and privileges */ uint save_master_access=thd->master_access; uint save_db_access= thd->db_access; + uint save_db_length= thd->db_length; char *save_user= thd->user; char *save_priv_user= thd->priv_user; char *save_db= thd->db; @@ -823,6 +826,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->master_access=save_master_access; thd->db_access=save_db_access; thd->db=save_db; + thd->db_length=save_db_length; thd->user=save_user; thd->priv_user=save_priv_user; break; @@ -836,23 +840,32 @@ bool dispatch_command(enum enum_server_command command, THD *thd, case COM_QUERY: { - char *pos=packet-1+packet_length; // Point at end null - /* Remove garage at end of query */ - while (packet_length > 0 && pos[-1] == ';') + packet_length--; // Remove end null + /* Remove garage at start and end of query */ + while (isspace(packet[0]) && packet_length > 0) + { + packet++; + packet_length--; + } + char *pos=packet+packet_length; // Point at end null + while (packet_length > 0 && (pos[-1] == ';' || isspace(pos[-1]))) { pos--; packet_length--; } - thd->query_length= packet_length; - if (!(thd->query= (char*) thd->memdup((gptr) (packet),packet_length+1))) + /* We must allocate some extra memory for query cache */ + if (!(thd->query= (char*) thd->memdup_w_gap((gptr) (packet), + packet_length, + thd->db_length+2))) break; thd->query[packet_length]=0; thd->packet.shrink(net_buffer_length); // Reclaim some memory if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(),QUERY_PRIOR); mysql_log.write(thd,command,"%s",thd->query); - DBUG_PRINT("query",("%s",thd->query)); - mysql_parse(thd,thd->query,packet_length-1); + DBUG_PRINT("query",("'%s'",thd->query)); + /* thd->query_length is set by mysql_parse() */ + mysql_parse(thd,thd->query,packet_length); if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(),WAIT_PRIOR); DBUG_PRINT("info",("query ready")); @@ -876,6 +889,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->free_list=0; table_list.name=table_list.real_name=thd->strdup(packet); packet=strend(packet)+1; + // command not cachable => no gap for data base name if (!(thd->query=fields=thd->memdup(packet,thd->query_length+1))) break; mysql_log.write(thd,command,"%s %s",table_list.real_name,fields); @@ -1100,6 +1114,29 @@ mysql_execute_command(void) SELECT_LEX *select_lex = lex->select; DBUG_ENTER("mysql_execute_command"); + if (thd->slave_thread) + { + /* + Skip if we are in the slave thread, some table rules have been + given and the table list says the query should not be replicated + */ + if (table_rules_on && tables && !tables_ok(thd,tables)) + DBUG_VOID_RETURN; +#ifndef TO_BE_DELETED + /* + This is a workaround to deal with the shortcoming in 3.23.44-3.23.46 + masters in RELEASE_LOCK() logging. We re-write SELECT RELEASE_LOCK() + as DO RELEASE_LOCK() + */ + if (lex->sql_command == SQLCOM_SELECT) + { + lex->sql_command = SQLCOM_DO; + lex->insert_list = &select_lex->item_list; + } +#endif + } + + thread_safe_increment(com_stat[lex->sql_command],&LOCK_thread_count); /* Skip if we are in the slave thread, some table rules have been given and the table list says the query should not be replicated @@ -2231,7 +2268,7 @@ error: bool check_access(THD *thd,uint want_access,const char *db, uint *save_priv, - bool dont_check_global_grants) + bool dont_check_global_grants, bool no_errors) { uint db_access,dummy; if (save_priv) @@ -2241,7 +2278,8 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv, if ((!db || !db[0]) && !thd->db && !dont_check_global_grants) { - send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: tested */ + if (!no_errors) + send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: tested */ return TRUE; /* purecov: tested */ } @@ -2253,10 +2291,11 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv, if ((want_access & ~thd->master_access) & ~(DB_ACLS | EXTRA_ACL) || ! db && dont_check_global_grants) { // We can never grant this - net_printf(&thd->net,ER_ACCESS_DENIED_ERROR, - thd->priv_user, - thd->host_or_ip, - thd->password ? ER(ER_YES) : ER(ER_NO));/* purecov: tested */ + if (!no_errors) + net_printf(&thd->net,ER_ACCESS_DENIED_ERROR, + thd->priv_user, + thd->host_or_ip, + thd->password ? ER(ER_YES) : ER(ER_NO));/* purecov: tested */ return TRUE; /* purecov: tested */ } @@ -2276,10 +2315,11 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv, ((grant_option && !dont_check_global_grants) && !(want_access & ~TABLE_ACLS))) return FALSE; /* Ok */ - net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR, - thd->priv_user, - thd->host_or_ip, - db ? db : thd->db ? thd->db : "unknown"); /* purecov: tested */ + if (!no_errors) + net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR, + thd->priv_user, + thd->host_or_ip, + db ? db : thd->db ? thd->db : "unknown"); /* purecov: tested */ return TRUE; /* purecov: tested */ } @@ -2296,7 +2336,8 @@ bool check_process_priv(THD *thd) */ bool -check_table_access(THD *thd,uint want_access,TABLE_LIST *tables) +check_table_access(THD *thd,uint want_access,TABLE_LIST *tables, + bool no_errors) { uint found=0,found_access=0; TABLE_LIST *org_tables=tables; @@ -2311,18 +2352,20 @@ check_table_access(THD *thd,uint want_access,TABLE_LIST *tables) tables->grant.privilege=found_access; else { - if (check_access(thd,want_access,tables->db,&tables->grant.privilege)) + if (check_access(thd,want_access,tables->db,&tables->grant.privilege, + 0, no_errors)) return TRUE; // Access denied found_access=tables->grant.privilege; found=1; } } - else if (check_access(thd,want_access,tables->db,&tables->grant.privilege)) + else if (check_access(thd,want_access,tables->db,&tables->grant.privilege, + 0, no_errors)) return TRUE; // Access denied } if (grant_option) return check_grant(thd,want_access & ~EXTRA_ACL,org_tables, - test(want_access & EXTRA_ACL)); + test(want_access & EXTRA_ACL), no_errors); return FALSE; } @@ -2444,6 +2487,7 @@ mysql_init_query(THD *thd) thd->fatal_error=0; // Safety thd->last_insert_id_used=thd->query_start_used=thd->insert_id_used=0; thd->sent_row_count=thd->examined_row_count=0; + thd->safe_to_cache_query=1; DBUG_VOID_RETURN; } @@ -2492,9 +2536,8 @@ mysql_parse(THD *thd,char *inBuf,uint length) mysql_init_query(thd); thd->query_length = length; - if (query_cache.send_result_to_client(thd, inBuf, length)) + if (query_cache.send_result_to_client(thd, inBuf, length) <= 0) { - thd->safe_to_cache_query=1; LEX *lex=lex_start(thd, (uchar*) inBuf, length); if (!yyparse() && ! thd->fatal_error) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index d4324a4e5ac..6ded046ccbf 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -430,7 +430,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, if (key->type == Key::FULLTEXT) { - if (file->option_flag() & HA_NO_FULLTEXT_KEY) + if (!(file->option_flag() & HA_CAN_FULLTEXT)) { my_error(ER_TABLE_CANT_HANDLE_FULLTEXT, MYF(0)); DBUG_RETURN(-1); @@ -558,9 +558,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, } } key_info->key_length=(uint16) key_length; - if (key_length > file->max_key_length() && key->type != Key::FULLTEXT) + uint max_key_length= max(file->max_key_length(), MAX_KEY_LENGTH); + if (key_length > max_key_length && key->type != Key::FULLTEXT) { - my_error(ER_TOO_LONG_KEY,MYF(0),file->max_key_length()); + my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length); DBUG_RETURN(-1); } } diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 3ee4b9ff37e..9493f969802 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -139,7 +139,8 @@ void udf_init() new_thd->version = refresh_version; //current_thd->version; new_thd->current_tablenr = 0; new_thd->open_tables = 0; - new_thd->db = my_strdup("mysql", MYF(0)); + new_thd->db= my_strdup("mysql", MYF(0)); + new_thd->db_length=5; bzero((gptr) &tables,sizeof(tables)); tables.name = tables.real_name = (char*) "func"; diff --git a/tests/mail_to_db.pl b/tests/mail_to_db.pl index fa2af91d9b2..aa0d3c51368 100755 --- a/tests/mail_to_db.pl +++ b/tests/mail_to_db.pl @@ -17,7 +17,7 @@ use DBI; use Getopt::Long; $| = 1; -$VER = "2.3"; +$VER = "2.4"; $opt_help = 0; $opt_version = 0; @@ -213,12 +213,12 @@ sub process_mail_file %values = (); $type = ""; $check = 0; - while (<FILE>) { chop; + chop if (substr($_, -1, 1) eq "\r"); if ($type ne "message") - { + { if (/^Reply-To: (.*)/i) { $type = "reply"; |