diff options
73 files changed, 1398 insertions, 1021 deletions
diff --git a/.bzrignore b/.bzrignore index 5d5909ce4da..a18a5008cb0 100644 --- a/.bzrignore +++ b/.bzrignore @@ -531,3 +531,7 @@ vio/test-sslclient vio/test-sslserver vio/viotest-ssl support-files/MacOSX/ReadMe.txt +Docs/internals.html +Docs/internals.pdf +Docs/internals.txt +Docs/internals_toc.html diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index aca77159202..8074f38541a 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -79,6 +79,7 @@ salle@geopard.(none) salle@geopard.online.bg sasha@mysql.sashanet.com serg@build.mysql2.com +serg@serg.mylan serg@serg.mysql.com serg@sergbook.mysql.com sinisa@rhols221.adsl.netsonic.fi diff --git a/Docs/internals.texi b/Docs/internals.texi index 07eea90e229..a54f5098e5d 100644 --- a/Docs/internals.texi +++ b/Docs/internals.texi @@ -43,18 +43,18 @@ END-INFO-DIR-ENTRY @page @end titlepage -@node Top, caching, (dir), (dir) +@node Top, coding guidelines, (dir), (dir) @ifinfo This is a manual about @strong{MySQL} internals. @end ifinfo @menu +* coding guidelines:: Coding Guidelines * caching:: How MySQL Handles Caching -* join_buffer_size:: +* join_buffer_size:: * flush tables:: How MySQL Handles @code{FLUSH TABLES} -* filesort:: How MySQL Does Sorting (@code{filesort}) -* coding guidelines:: Coding Guidelines +* Algorithms:: * mysys functions:: Functions In The @code{mysys} Library * DBUG:: DBUG Tags To Use * protocol:: MySQL Client/Server Protocol @@ -67,7 +67,166 @@ This is a manual about @strong{MySQL} internals. @end menu -@node caching, join_buffer_size, Top, Top +@node coding guidelines, caching, Top, Top +@chapter Coding Guidelines + +@itemize @bullet + +@item +We use @uref{http://www.bitkeeper.com/, BitKeeper} for source management. + +@item +You should use the @strong{MySQL} 4.1 source for all developments. + +@item +If you have any questions about the @strong{MySQL} source, you can post these +to @email{internals@@mysql.com} and we will answer them. + +@item +Try to write code in a lot of black boxes that can be reused or use at +least a clean, easy to change interface. + +@item +Reuse code; There is already a lot of algorithms in MySQL for list handling, +queues, dynamic and hashed arrays, sorting, etc. that can be reused. + +@item +Use the @code{my_*} functions like @code{my_read()}/@code{my_write()}/ +@code{my_malloc()} that you can find in the @code{mysys} library instead +of the direct system calls; This will make your code easier to debug and +more portable. + +@item +Try to always write optimized code, so that you don't have to +go back and rewrite it a couple of months later. It's better to +spend 3 times as much time designing and writing an optimal function than +having to do it all over again later on. + +@item +Avoid CPU wasteful code, even where it does not matter, so that +you will not develop sloppy coding habits. + +@item +If you can write it in fewer lines, do it (as long as the code will not +be slower or much harder to read). + +@item +Don't use two commands on the same line. + +@item +Do not check the same pointer for @code{NULL} more than once. + +@item +Use long function and variable names in English. This makes your code +easier to read. + +@item +Use @code{my_var} as opposed to @code{myVar} or @code{MyVar} (@samp{_} +rather than dancing SHIFT to seperate words in identifiers). + +@item +Think assembly - make it easier for the compiler to optimize your code. + +@item +Comment your code when you do something that someone else may think +is not ``trivial''. + +@item +Use @code{libstring} functions (in the @file{strings} directory) +instead of standard @code{libc} string functions whenever possible. + +@item +Avoid using @code{malloc()} (its REAL slow); For memory allocations +that only need to live for the lifetime of one thread, one should use +@code{sql_alloc()} instead. + +@item +Before making big design decisions, please first post a summary of +what you want to do, why you want to do it, and how you plan to do +it. This way we can easily provide you with feedback and also +easily discuss it thoroughly if some other developer thinks there is better +way to do the same thing! + +@item +Class names start with a capital letter. + +@item +Structure types are @code{typedef}'ed to an all-caps identifier. + +@item +Any @code{#define}'s are in all-caps. + +@item +Matching @samp{@{} are in the same column. + +@item +Put the @samp{@{} after a @code{switch} on the same line, as this gives +better overall indentation for the switch statement: + +@example +switch (arg) @{ +@end example + +@item +In all other cases, @samp{@{} and @samp{@}} should be on their own line, except +if there is nothing inside @samp{@{} and @samp{@}}. + +@item +Have a space after @code{if} + +@item +Put a space after @samp{,} for function arguments + +@item +Functions return @samp{0} on success, and non-zero on error, so you can do: + +@example +if(a() || b() || c()) @{ error("something went wrong"); @} +@end example + +@item +Using @code{goto} is okay if not abused. + +@item +Avoid default variable initalizations, use @code{LINT_INIT()} if the +compiler complains after making sure that there is really no way +the variable can be used uninitialized. + +@item +Do not instantiate a class if you do not have to. + +@item +Use pointers rather than array indexing when operating on strings. + +@end itemize + +Suggested mode in emacs: + +@example +(load "cc-mode") +(setq c-mode-common-hook '(lambda () + (turn-on-font-lock) + (setq comment-column 48))) +(setq c-style-alist + (cons + '("MY" + (c-basic-offset . 2) + (c-comment-only-line-offset . 0) + (c-offsets-alist . ((statement-block-intro . +) + (knr-argdecl-intro . 0) + (substatement-open . 0) + (label . -) + (statement-cont . +) + (arglist-intro . c-lineup-arglist-intro-after-paren) + (arglist-close . c-lineup-arglist) + )) + ) + c-style-alist)) +(c-set-style "MY") +(setq c-default-style "MY") +@end example + +@node caching, join_buffer_size, coding guidelines, Top @chapter How MySQL Handles Caching @strong{MySQL} has the following caches: @@ -181,7 +340,7 @@ same algorithm described above to handle it. (In other words, we store the same row combination several times into different buffers) @end itemize -@node flush tables, filesort, join_buffer_size, Top +@node flush tables, Algorithms, join_buffer_size, Top @chapter How MySQL Handles @code{FLUSH TABLES} @itemize @bullet @@ -226,8 +385,19 @@ After this it will give other threads a chance to open the same tables. @end itemize -@node filesort, coding guidelines, flush tables, Top -@chapter How MySQL Does Sorting (@code{filesort}) +@node Algorithms, mysys functions, flush tables, Top +@chapter Different algoritms used in MySQL + +MySQL uses a lot of different algorithms. This chapter tries to describe +some of these: + +@menu +* filesort:: +* bulk-insert:: +@end menu + +@node filesort, bulk-insert, Algorithms, Algorithms +@section How MySQL Does Sorting (@code{filesort}) @itemize @bullet @@ -266,169 +436,20 @@ and then we read the rows in the sorted order into a row buffer @end itemize +@node bulk-insert, , filesort, Algorithms +@section Bulk insert -@node coding guidelines, mysys functions, filesort, Top -@chapter Coding Guidelines - -@itemize @bullet - -@item -We are using @uref{http://www.bitkeeper.com/, BitKeeper} for source management. - -@item -You should use the @strong{MySQL} 4.0 source for all developments. - -@item -If you have any questions about the @strong{MySQL} source, you can post these -to @email{dev-public@@mysql.com} and we will answer them. Please -remember to not use this internal email list in public! - -@item -Try to write code in a lot of black boxes that can be reused or use at -least a clean, easy to change interface. - -@item -Reuse code; There is already a lot of algorithms in MySQL for list handling, -queues, dynamic and hashed arrays, sorting, etc. that can be reused. - -@item -Use the @code{my_*} functions like @code{my_read()}/@code{my_write()}/ -@code{my_malloc()} that you can find in the @code{mysys} library instead -of the direct system calls; This will make your code easier to debug and -more portable. - -@item -Try to always write optimized code, so that you don't have to -go back and rewrite it a couple of months later. It's better to -spend 3 times as much time designing and writing an optimal function than -having to do it all over again later on. - -@item -Avoid CPU wasteful code, even where it does not matter, so that -you will not develop sloppy coding habits. - -@item -If you can write it in fewer lines, do it (as long as the code will not -be slower or much harder to read). - -@item -Don't use two commands on the same line. - -@item -Do not check the same pointer for @code{NULL} more than once. - -@item -Use long function and variable names in English. This makes your code -easier to read. - -@item -Use @code{my_var} as opposed to @code{myVar} or @code{MyVar} (@samp{_} -rather than dancing SHIFT to seperate words in identifiers). - -@item -Think assembly - make it easier for the compiler to optimize your code. - -@item -Comment your code when you do something that someone else may think -is not ``trivial''. - -@item -Use @code{libstring} functions (in the @file{strings} directory) -instead of standard @code{libc} string functions whenever possible. - -@item -Avoid using @code{malloc()} (its REAL slow); For memory allocations -that only need to live for the lifetime of one thread, one should use -@code{sql_alloc()} instead. - -@item -Before making big design decisions, please first post a summary of -what you want to do, why you want to do it, and how you plan to do -it. This way we can easily provide you with feedback and also -easily discuss it thoroughly if some other developer thinks there is better -way to do the same thing! +Logic behind bulk insert optimisation is simple. -@item -Class names start with a capital letter. +Instead of writing each key value to b-tree (that is to keycache, but +bulk insert code doesn't know about keycache) keys are stored in +balanced binary (red-black) tree, in memory. When this tree reaches its +memory limit it's writes all keys to disk (to keycache, that is). But +as key stream coming from the binary tree is already sorted inserting +goes much faster, all the necessary pages are already in cache, disk +access is minimized, etc. -@item -Structure types are @code{typedef}'ed to an all-caps identifier. - -@item -Any @code{#define}'s are in all-caps. - -@item -Matching @samp{@{} are in the same column. - -@item -Put the @samp{@{} after a @code{switch} on the same line, as this gives -better overall indentation for the switch statement: - -@example -switch (arg) @{ -@end example - -@item -In all other cases, @samp{@{} and @samp{@}} should be on their own line, except -if there is nothing inside @samp{@{} and @samp{@}}. - -@item -Have a space after @code{if} - -@item -Put a space after @samp{,} for function arguments - -@item -Functions return @samp{0} on success, and non-zero on error, so you can do: - -@example -if(a() || b() || c()) @{ error("something went wrong"); @} -@end example - -@item -Using @code{goto} is okay if not abused. - -@item -Avoid default variable initalizations, use @code{LINT_INIT()} if the -compiler complains after making sure that there is really no way -the variable can be used uninitialized. - -@item -Do not instantiate a class if you do not have to. - -@item -Use pointers rather than array indexing when operating on strings. - -@end itemize - -Suggested mode in emacs: - -@example -(load "cc-mode") -(setq c-mode-common-hook '(lambda () - (turn-on-font-lock) - (setq comment-column 48))) -(setq c-style-alist - (cons - '("MY" - (c-basic-offset . 2) - (c-comment-only-line-offset . 0) - (c-offsets-alist . ((statement-block-intro . +) - (knr-argdecl-intro . 0) - (substatement-open . 0) - (label . -) - (statement-cont . +) - (arglist-intro . c-lineup-arglist-intro-after-paren) - (arglist-close . c-lineup-arglist) - )) - ) - c-style-alist)) -(c-set-style "MY") -(setq c-default-style "MY") -@end example - - -@node mysys functions, DBUG, coding guidelines, Top +@node mysys functions, DBUG, Algorithms, Top @chapter Functions In The @code{mysys} Library Functions in @code{mysys}: (For flags see @file{my_sys.h}) @@ -624,6 +645,16 @@ Print query. * fieldtype codes:: * protocol functions:: * protocol version 2:: +* 4.1 protocol changes:: +* 4.1 field packet:: +* 4.1 field desc:: +* 4.1 ok packet:: +* 4.1 end packet:: +* 4.1 error packet:: +* 4.1 prep init:: +* 4.1 long data:: +* 4.1 execute:: +* 4.1 binary result:: @end menu @node raw packet without compression, raw packet with compression, protocol, protocol @@ -745,6 +776,7 @@ For details, see @file{sql/net_pkg.cc::send_ok()}. @node communication, fieldtype codes, basic packets, protocol @section Communication +@example > Packet from server to client < Paket from client tor server @@ -832,7 +864,7 @@ For details, see @file{sql/net_pkg.cc::send_ok()}. 4 byte header 1-8 byte length of data n data - +@end example @node fieldtype codes, protocol functions, communication, protocol @section Fieldtype Codes @@ -861,7 +893,9 @@ Date 03 0A 00 00 |01 0A |03 00 00 00 @node protocol functions, protocol version 2, fieldtype codes, protocol @section Functions used to implement the protocol -This should be merged with the above one and changed to texi format +@c This should be merged with the above one and changed to texi format + +@example Raw packets ----------- @@ -966,12 +1000,14 @@ The encrypted message is sent to the server which uses the stored random number password to encrypt the random string sent to the client. If this is equal to the new message the client sends to the server then the password is accepted. +@end example -@node protocol version 2, , protocol functions, protocol +@node protocol version 2, 4.1 protocol changes, protocol functions, protocol @section Another description of the protocol -This should be merged with the above one and changed to texi format. +@c This should be merged with the above one and changed to texi format. +@example ***************************** * * PROTOCOL OVERVIEW @@ -1646,7 +1682,7 @@ one packet is sent from the server, for simplicity's sake): Followed immediately by one 'LAST DATA' packet: fe 00 . . - +@end example @c The Index was empty, and ugly, so I removed it. (jcole, Sep 7, 2000) @@ -1659,7 +1695,7 @@ fe 00 . . @c @node 4.1 protocol,,, @c @chapter MySQL 4.1 protocol -@node 4.1 protocol changes,,, +@node 4.1 protocol changes, 4.1 field packet, protocol version 2, protocol @section Changes to 4.0 protocol in 4.1 All basic packet handling is identical to 4.0. When communication @@ -1694,7 +1730,7 @@ results will sent as binary (low-byte-first). @end itemize -@node 4.1 field packet,,, +@node 4.1 field packet, 4.1 field desc, 4.1 protocol changes, protocol @section 4.1 field description packet The field description packet is sent as a response to a query that @@ -1714,7 +1750,7 @@ uses this to send the number of rows in the table) This packet is always followed by a field description set. @xref{4.1 field desc}. -@node 4.1 field desc,,, +@node 4.1 field desc, 4.1 ok packet, 4.1 field packet, protocol @section 4.1 field description result set The field description result set contains the meta info for a result set. @@ -1732,7 +1768,7 @@ The field description result set contains the meta info for a result set. @end multitable -@node 4.1 ok packet,,, +@node 4.1 ok packet, 4.1 end packet, 4.1 field desc, protocol @section 4.1 ok packet The ok packet is the first that is sent as an response for a query @@ -1758,7 +1794,7 @@ The message is optional. For example for multi line INSERT it contains a string for how many rows was inserted / deleted. -@node 4.1 end packet,,, +@node 4.1 end packet, 4.1 error packet, 4.1 ok packet, protocol @section 4.1 end packet The end packet is sent as the last packet for @@ -1787,7 +1823,7 @@ by checking the packet length < 9 bytes (in which case it's and end packet). -@node 4.1 error packet +@node 4.1 error packet, 4.1 prep init, 4.1 end packet, protocol @section 4.1 error packet. The error packet is sent when something goes wrong. @@ -1804,7 +1840,7 @@ The client/server protocol is designed in such a way that a packet can only start with 255 if it's an error packet. -@node 4.1 prep init,,, +@node 4.1 prep init, 4.1 long data, 4.1 error packet, protocol @section 4.1 prepared statement init packet This is the return packet when one sends a query with the COM_PREPARE @@ -1838,7 +1874,7 @@ prepared statement will contain a result set. In this case the packet is followed by a field description result set. @xref{4.1 field desc}. -@node 4.1 long data,,, +@node 4.1 long data, 4.1 execute, 4.1 prep init, protocol @section 4.1 long data handling This is used by mysql_send_long_data() to set any parameter to a string @@ -1865,7 +1901,7 @@ The server will NOT send an @code{ok} or @code{error} packet in responce for this. If there is any errors (like to big string), one will get the error when calling execute. -@node 4.1 execute,,, +@node 4.1 execute, 4.1 binary result, 4.1 long data, protocol @section 4.1 execute On execute we send all parameters to the server in a COM_EXECUTE @@ -1903,7 +1939,7 @@ The parameters are stored the following ways: The result for this will be either an ok packet or a binary result set. -@node 4.1 binary result,,, +@node 4.1 binary result, , 4.1 execute, protocol @section 4.1 binary result set A binary result are sent the following way. @@ -2009,12 +2045,15 @@ And if you use Windows, you might find the files in this directory: @* @*@* Let's look at the .MYD Data file (MyISAM SQL Data file) more closely. +There are three possible formats -- fixed, dynamic, and packed. First, +let's discuss the fixed format. + @table @strong @item Page Size Unlike most DBMSs, MySQL doesn't store on disk using pages. Therefore you will not see filler space between rows. (Reminder: This does not -refer to BDB and INNODB tables, which do use pages). +refer to BDB and InnoDB tables, which do use pages). @* @item Record Header @@ -2032,8 +2071,8 @@ The minimal record header is a set of flags: The length of the record header is thus:@* (1 + number of NULL columns + 7) / 8 bytes@* -After the header, all columns are stored in -the order that they were created, which is the +After the header, all columns are stored in +the order that they were created, which is the same order that you would get from SHOW COLUMNS. Here's an example. Suppose you say: @@ -2078,10 +2117,73 @@ right is @code{on}, and (b) remember that the first flag bit is the X bit.) There are complications -- the record header is more complex if there are variable-length fields -- but the simple display shown in the -example is exactly what you'd see if you looked at the MySQL Data file +example is exactly what you'd see if you looked at the MySQL Data file with a debugger or a hexadecimal file dumper. @* +So much for the fixed format. Now, let's discuss the dynamic format. +@* + +The dynamic file format is necessary if rows can vary in size. That will +be the case if there are BLOB columns, or "true" VARCHAR columns. (Remember +that MySQL may treat VARCHAR columns as if they're CHAR columns, in which +case the fixed format is used.) A dynamic row has more fields in the header. +The important ones are "the actual length", "the unused length", and "the +overflow pointer". The actual length is the total number of bytes in all the +columns. The unused length is the total number of bytes between one physical +record and the next one. The overflow pointer is the location of the rest of +the record if there are multiple parts. +@* + +For example, here is a dynamic row: +@* +@example +03, 00 start of header +04 actual length +0c unused length +01, fc flags + overflow pointer +**** data in the row +************ unused bytes + <-- next row starts here) +@end example + +In the example, the actual length and the unused length +are short (one byte each) because the table definition +says that the columns are short -- if the columns were +potentially large, then the actual length and the unused +length could be two bytes each, three bytes each, and so +on. In this case, actual length plus unused length is 10 +hexadecimal (sixteen decimal), which is a minimum. + +As for the third format -- packed -- we will only say +briefly that: +@itemize @bullet +@item +Numeric values are stored in a form that depends on the +range (start/end values) for the data type. +@item +All columns are packed using either Huffman or enum coding. +@end itemize + +For details, see the source files /myisam/mi_statrec.c +(for fixed format), /myisam/mi_dynrec.c (for dynamic +format), and /myisam/mi_packrec.c (for packed format). + +Note: Internally, MySQL uses a format much like the fixed format +which it uses for disk storage. The main differences are: +@enumerate +@item +BLOBs have a length and a memory pointer rather than being stored inline. +@item +"True VARCHAR" (a column storage which will be fully implemented in +version 5.0) will have a 16-bit length plus the data. +@item +All integer or floating-point numbers are stored with the low byte first. +Point (3) does not apply for ISAM storage or internals. +@end enumerate +@* + + @section Physical Attributes of Columns Next I'll describe the physical attributes of each column in a row. @@ -2304,9 +2406,6 @@ of correspondence between the BLOB and the INT types. There isn't -- a BLOB's preceding length is not four bytes long (the size of an INT). @* -(NOTE TO SELF: BLOB storage has not been fully addressed here.) -@* - @strong{TINYBLOB} @itemize @bullet @item @@ -2379,7 +2478,7 @@ work for different record formats are: /myisam/mi_statrec.c, /myisam/mi_dynrec.c, and /myisam/mi_packrec.c. @* -@node InnoDB Record Structure,InnoDB Page Structure,MyISAM Record Structure,Top +@node InnoDB Record Structure, InnoDB Page Structure, MyISAM Record Structure, Top @chapter InnoDB Record Structure This page contains: @@ -2685,7 +2784,7 @@ shorter because the NULLs take no space. The most relevant InnoDB source-code files are rem0rec.c, rem0rec.ic, and rem0rec.h in the rem ("Record Manager") directory. -@node InnoDB Page Structure,Files in MySQL Sources,InnoDB Record Structure,Top +@node InnoDB Page Structure, Files in MySQL Sources, InnoDB Record Structure, Top @chapter InnoDB Page Structure InnoDB stores all records inside a fixed-size unit which is commonly called a @@ -3116,7 +3215,7 @@ header. The most relevant InnoDB source-code files are page0page.c, page0page.ic, and page0page.h in \page directory. -@node Files in MySQL Sources,Files in InnoDB Sources,InnoDB Page Structure,Top +@node Files in MySQL Sources, Files in InnoDB Sources, InnoDB Page Structure, Top @chapter Annotated List Of Files in the MySQL Source Code Distribution This is a description of the files that you get when you download the @@ -3131,42 +3230,38 @@ program is given along with an explanation of its intended function. @strong{Directory -- Short Comment} @itemize @bullet @item -bdb -- The Berkeley Database table handler +bdb -- The Berkeley Database table handler @item BitKeeper -- BitKeeper administration (not part of the source distribution) @item -BUILD -- Some very often used build scripts +BUILD -- Frequently used build scripts @item -Build-tools -- Build tools +Build-tools -- Build tools (not part of the source distribution) @item -client -- Client library +client -- Client library @item cmd-line-utils -- Command-line utilities (libedit and readline) @item dbug -- Fred Fish's dbug library @item -Docs -- Preliminary documents about internals and new modules +Docs -- Preliminary documents about internals and new modules; will eventually be moved to the mysqldoc repository @item extra -- Some minor standalone utility programs @item heap -- The HEAP table handler @item -include -- Include (*.h) files +include -- Header (*.h) files for most libraries; includes all header files distributed with the MySQL binary distribution @item innobase -- The Innobase (InnoDB) table handler @item -isam -- The ISAM (MySQL) table handler +libmysql -- For producing MySQL as a library (e.g. a Windows .DLL) @item -libmysql -- For producing a thread-safe libmysql library -@item -libmysql_r -- Only one file, a makefile +libmysql_r -- For building a thread-safe libmysql library @item libmysqld -- The MySQL Server as an embeddable library @item man -- Some user-contributed manual pages @item -merge -- The MERGE table handler (see Reference Manual section 7.2) -@item myisam -- The MyISAM table handler @item myisammrg -- The MyISAM Merge table handler @@ -3177,9 +3272,9 @@ mysys -- MySQL system library (Low level routines for file access etc.) @item netware -- Files related to the Novell NetWare version of MySQL @item -NEW-RPMS -- Directory to place RPMS while making a distribution +NEW-RPMS -- Directory to place RPMs while making a distribution @item -os2 -- Routines for working with the OS/2 operating system +os2 -- Routines for working with the OS/2 operating system @item pstack -- Process stack display (not currently used) @item @@ -3189,25 +3284,25 @@ SCCS -- Source Code Control System (not part of source distribution) @item scripts -- SQL batches, e.g. mysqlbug and mysql_install_db @item -sql -- Programs for handling SQL commands. The "core" of MySQL +sql -- Programs for handling SQL commands; the "core" of MySQL @item sql-bench -- The MySQL benchmarks @item -SSL -- Secure Sockets Layer +SSL -- Secure Sockets Layer; includes an example certification one can use to test an SSL (secure) database connection @item strings -- Library for C string routines, e.g. atof, strchr @item support-files -- Files used to build MySQL on different systems @item -tests -- Tests in Perl +tests -- Tests in Perl and in C @item -tools -- mysqlmanager.c (under development, not yet useful) +tools -- mysqlmanager.c (tool under development, not yet useful) @item VC++Files -- Includes this entire directory, repeated for VC++ (Windows) use @item vio -- Virtual I/O Library @item -zlib -- data compression library, used on Windows +zlib -- Data compression library, used on Windows @end itemize @subsection bdb @@ -3215,7 +3310,7 @@ zlib -- data compression library, used on Windows The Berkeley Database table handler. @*@* -The Berkeley Database (BDB) is maintained by Sleepycat Software. +The Berkeley Database (BDB) is maintained by Sleepycat Software. MySQL AB maintains only a few small patches to make BDB work better with MySQL. @*@* @@ -3231,19 +3326,21 @@ in this document. BitKeeper administration. @*@* -This directory may be present if you downloaded the MySQL source using +Bitkeeper administration is not part of the source distribution. This +directory may be present if you downloaded the MySQL source using BitKeeper rather than via the mysql.com site. The files in the BitKeeper directory are for maintenance purposes only -- they are not part of the MySQL package. @*@* -The MySQL Reference Manual explains how to use Bitkeeper to get the -MySQL source. +The MySQL Reference Manual explains how to use Bitkeeper to get the +MySQL source. Please see @url{http://www.mysql.com/doc/en/Installing_source_tree.html} +for more information. @*@* @subsection BUILD -Build switches. +Frequently used build scripts. @*@* This directory contains the build switches for compilation on various @@ -3266,11 +3363,11 @@ solaris Build tools. @*@* -This directory contains batch files for extracting, making -directories, and making programs from source files. There are -several subdirectories with different scripts -- for building -Linux executables, for compiling, for performing all build steps, -and so on. +Build-tools is not part of the source distribution. This directory +contains batch files for extracting, making directories, and making +programs from source files. There are several subdirectories with +different scripts -- for building Linux executables, for compiling, +for performing all build steps, and so on. @*@* @subsection client @@ -3288,21 +3385,15 @@ server. The C program files in the directory are: @itemize @bullet @item -connect_test.c -- test that a connect is possible -@item get_password.c -- ask for a password from the console @item -insert_test.c -- test that an insert is possible -@item -list_test.c -- test that a select is possible -@item mysql.cc -- "The MySQL command tool" @item -mysqladmin.c -- maintenance of MYSQL databases +mysqladmin.c -- maintenance of MySQL databases @item mysqlcheck.c -- check all databases, check connect, etc. @item -mysqldump.c -- dump table's contents as SQL statements +mysqldump.c -- dump table's contents as SQL statements, suitable to backup a MySQL database @item mysqlimport.c -- import text files in different formats into tables @item @@ -3314,29 +3405,20 @@ mysqlshow.c -- show databases, tables or columns @item mysqltest.c -- test program used by the mysql-test suite, mysql-test-run @item -password.c -- password checking routines -@item -select_test.c -- test that a select is possible -@item -showdb_test.c -- test that a show-databases is possible -@item -ssl_test.c -- test that SSL is possible -@item -thread_test.c -- test that threading is possible +password.c -- password checking routines (version 4.1 and up) @end itemize @*@* @subsection cmd-line-utils -Command-line utilities. +Command-line utilities (libedit and readline). @*@* There are two subdirectories: \readline and \libedit. All the files -here are "non-MYSQL" files, in the sense that MySQL AB didn't produce +here are "non-MySQL" files, in the sense that MySQL AB didn't produce them, it just uses them. It should be unnecessary to study the -programs in these files unless -you are writing or debugging a tty-like client for MySQL, such as -mysql.exe. +programs in these files unless you are writing or debugging a tty-like +client for MySQL, such as mysql.exe. @*@* The \readline subdirectory contains the files of the GNU Readline @@ -3346,54 +3428,54 @@ Software Foundation. @*@* The \libedit (library of edit functions) subdirectory has files -written by Christos Zoulas. They are distributed and modifed under +written by Christos Zoulas. They are distributed and modifed under the BSD License. These files are for editing the line contents. @*@* These are the program files in the \libedit subdirectory: @itemize @bullet @item -chared.c -- character editor +chared.c -- character editor @item -common.c -- common editor functions +common.c -- common editor functions @item -el.c -- editline interface functions +el.c -- editline interface functions @item -emacs.c -- emacs functions +emacs.c -- emacs functions @item -fgetln.c -- get line +fgetln.c -- get line @item -hist.c -- history access functions +hist.c -- history access functions @item -history.c -- more history access functions +history.c -- more history access functions @item -key.c -- procedures for maintaining the extended-key map +key.c -- procedures for maintaining the extended-key map @item -map.c -- editor function definitions +map.c -- editor function definitions @item -parse.c -- parse an editline extended command +parse.c -- parse an editline extended command @item -prompt.c -- prompt printing functions +prompt.c -- prompt printing functions @item -read.c -- terminal read functions +read.c -- terminal read functions @item -readline.c -- read line +readline.c -- read line @item -refresh.c -- "lower level screen refreshing functions" +refresh.c -- "lower level screen refreshing functions" @item -search.c -- "history and character search functions" +search.c -- "history and character search functions" @item -sig.c -- for signal handling +sig.c -- for signal handling @item -strlcpy.c -- string copy +strlcpy.c -- string copy @item -term.c -- "editor/termcap-curses interface" +term.c -- "editor/termcap-curses interface" @item -tokenizer.c -- Bourne shell line tokenizer +tokenizer.c -- Bourne shell line tokenizer @item -tty.c -- for a tty interface +tty.c -- for a tty interface @item -vi.c -- commands used when in the vi (editor) mode +vi.c -- commands used when in the vi (editor) mode @end itemize @*@* @@ -3403,8 +3485,8 @@ Fred Fish's dbug library. @*@* This is not really part of the MySQL package. Rather, it's a set of -public-domain routines which are useful for debugging MySQL programs. -The MySQL Server and all .c and .cc programs support the use of this +public-domain routines which are useful for debugging MySQL programs. +The MySQL Server and all .c and .cc programs support the use of this package. @*@* @@ -3415,61 +3497,62 @@ DBUG_ENTER("get_tty_password"); @* at the start of a routine, and this line: @* DBUG_RETURN(my_strdup(to,MYF(MY_FAE))); @* at the end of the routine. These lines don't affect production code. -Features of the dbug library include extensive reporting and profiling +Features of the dbug library include extensive reporting and profiling (the latter has not been used by the MySQL team). @*@* The C programs in this directory are: @itemize @bullet @item -dbug.c -- The main module +dbug.c -- The main module @item -dbug_analyze.c -- Reads a file produced by trace functions +dbug_analyze.c -- Reads a file produced by trace functions @item -example1.c -- A tiny example +example1.c -- A tiny example @item -example2.c -- A tiny example +example2.c -- A tiny example @item -example3.c -- A tiny example +example3.c -- A tiny example @item -factorial.c -- A tiny example +factorial.c -- A tiny example @item -main.c -- A tiny example +main.c -- A tiny example @item -sanity.c -- Declaration of a variable +sanity.c -- Declaration of a variable @end itemize @*@* @subsection Docs -Preliminary documents about internals and new modules. +Preliminary documents about internals and new modules, which will eventually +be moved to the mysqldoc repository. @*@* This directory doesn't have much at present that's very useful to the student, but the plan is that some documentation related to the source files and the internal workings of MySQL, including perhaps some -documentation from developers themselves, will be placed here. Some of -these files will eventually be moved to the MySQL documentation repository. +documentation from developers themselves, will be placed here. Files in +this directory will eventually be moved to the MySQL documentation repository. @*@* These sub-directories are part of this directory: @itemize @bullet @item -books -- .gif images and empty .txt files; no real information +books -- .gif images and empty .txt files; no real information @item -flags -- images of flags of countries +flags -- images of flags of countries @item -images -- flag backgrounds and the MySQL dolphin logo +images -- flag backgrounds and the MySQL dolphin logo @item -mysql-logos -- more MySQL-related logos, some of them moving +mysql-logos -- more MySQL-related logos, some of them moving @item -raw-flags -- more country flags, all .gif files +raw-flags -- more country flags, all .gif files @item -support -- various files for generating texinfo/docbook documentation +support -- various files for generating texinfo/docbook documentation @item -to-be-included... -- an empty subdirectory +to-be-included... -- contains a MySQL-for-dummies file @item -translations -- some Portuguese myodbc documentation +translations -- some Portuguese myodbc documentation @end itemize @*@* @@ -3480,16 +3563,16 @@ has any importance -- internals.texi -- The "MySQL Internals" document. @*@* -Despite the name, internals.texi is not really much of a description -of MySQL internals. However, there is some useful description of the -functions in the mysys directory (see below), and of the structure of -client/server messages (doubtless very useful for people who want to -make their own JDBC drivers, or just sniff). +Despite the name, internals.texi is not yet much of a description of MySQL +internals although work is in progress to make it so. However, there is +some useful description of the functions in the mysys directory (see below), +and of the structure of client/server messages (doubtless very useful for +eople who want to make their own JDBC drivers, or just sniff). @*@* @subsection extra -Eight minor standalone utility programs. +Some minor standalone utility programs. @*@* These programs are all standalone utilities, that is, they have @@ -3498,56 +3581,20 @@ MySQL server needs or produces. Most are unimportant. They are as follows: @itemize @bullet @item -my_print_defaults.c -- print all parameters in a default file -@item -mysql_install.c -- startup: install MySQL server +my_print_defaults.c -- print parameters from my.ini files. Can also be used in scripts to enable processing of my.ini files. @item -mysql_waitpid.c -- wait for a program to terminate +mysql_waitpid.c -- wait for a program to terminate. Useful for shell scripts when one needs to wait until a process terminates. @item -perror.c -- "print error" -- given error number, display message +perror.c -- "print error" -- given error number, display message @item replace.c -- replace strings in text files or pipe @item -resolve_stack_dump.c -- show symbolic info from a stack dump +resolve_stack_dump.c -- show symbolic information from a MySQL stack dump, normally found in the mysql.err file @item -resolveip.c -- convert an IP address to a hostname, or vice versa +resolveip.c -- convert an IP address to a hostname, or vice versa @end itemize @*@* -@subsection fs - -File System. -@*@* - -Here the word "File System" does not refer to the mere idea of a -directory of files on a disk drive, but to object-based access. The -concept has been compared with Oracle's Internet File System (iFS). -@*@* - -The original developer of the files on this directory is Tonu Samuel, -a former MySQL AB employee. Here is a quote (somewhat edited) from -Tonu Samuel's web page (http://no.spam.ee/~tonu/index.php): -"Question: What is it? -Answer: Actually this is not filesystem in common terms. MySQL FS -makes it possible to make SQL tables and some functions available over -a filesystem. MySQL does not require disk space, it uses an ordinary -MySQL daemon to store data." -The descriptions imply that this is a development project. -@*@* - -There are four program files in the directory: -@itemize @bullet -@item -database.c -- "emulate filesystem behaviour on top of SQL database" -@item -libmysqlfs.c -- Search/replace, show-functions, and parse routines -@item -mysqlcorbafs.c -- Connection with the CORBA "Object Request Broker" -@item -mysqlcorbafs_test.c -- Utility to test the working of mysqlcorbafs.c - -@*@* - @subsection heap The HEAP table handler. @@ -3559,58 +3606,63 @@ produces) have files with similar names and functions. Thus, this (for the MyISAM table handler). Such duplicates have been marked with an "*" in the following list. For example, you will find that \heap\hp_extra.c has a close equivalent in the myisam directory -(\myisam\mi_extra.c) with the same descriptive comment. +(\myisam\mi_extra.c) with the same descriptive comment. (Some of the +differences arise because HEAP has different structures. HEAP does not +need to use the sort of B-tree indexing that ISAM and MyISAM use; instead +there is a hash index. Most importantly, HEAP is entirely in memory. +File-I/O routines lose some of their vitality in such a context.) @*@* +@itemize @item hp_block.c -- Read/write a block (i.e. a page) @item hp_clear.c -- Remove all records in the table @item -hp_close.c -- * close database +hp_close.c -- * close database @item -hp_create.c -- * create a table +hp_create.c -- * create a table @item -hp_delete.c -- * delete a row +hp_delete.c -- * delete a row @item hp_extra.c -- * for setting options and buffer sizes when optimizing @item -hp_hash.c -- Hash functions used for saving keys +hp_hash.c -- Hash functions used for saving keys @item -hp_info.c -- * Information about database status +hp_info.c -- * Information about database status @item -hp_open.c -- * open database +hp_open.c -- * open database @item hp_panic.c -- * the hp_panic routine, for shutdowns and flushes @item -hp_rename.c -- * rename a table +hp_rename.c -- * rename a table @item hp_rfirst.c -- * read first row through a specific key (very short) @item -hp_rkey.c -- * read record using a key +hp_rkey.c -- * read record using a key @item hp_rlast.c -- * read last row with same key as previously-read row @item hp_rnext.c -- * read next row with same key as previously-read row @item -hp_rprev.c -- * read previous row with same key as previously-read row +hp_rprev.c -- * read previous row with same key as previously-read row @item -hp_rrnd.c -- * read a row based on position +hp_rrnd.c -- * read a row based on position @item hp_rsame.c -- * find current row using positional read or key-based -read +read @item -hp_scan.c -- * read all rows sequentially +hp_scan.c -- * read all rows sequentially @item hp_static.c -- * static variables (very short) @item -hp_test1.c -- * testing basic functions +hp_test1.c -- * testing basic functions @item -hp_test2.c -- * testing database and storing results +hp_test2.c -- * testing database and storing results @item -hp_update.c -- * update an existing row +hp_update.c -- * update an existing row @item -hp_write.c -- * insert a new row +hp_write.c -- * insert a new row @end itemize @*@* @@ -3622,7 +3674,8 @@ for a \myisam\mi_cache.c equivalent (to cache reads) or a @subsection include -Include (*.h) files. +Header (*.h) files for most libraries; includes all header files distributed +with the MySQL binary distribution. @*@* These files may be included in C program files. Note that each @@ -3637,7 +3690,7 @@ rijndael.h. Looking further, you'll find that rijndael.h is also included in other places: by my_aes.c and my_aes.h. @*@* -The include directory contains 51 *.h (include) files. +The include directory contains 51 *.h (header) files. @*@* @subsection innobase @@ -3649,100 +3702,6 @@ A full description of these files can be found elsewhere in this document. @*@* -@subsection isam - -The ISAM table handler. -@*@* - -The C files in this directory are: -@itemize @bullet -@item -_cache.c -- for reading records from a cache -@item -changed.c -- a single routine for setting a "changed" flag (very -short) -@item -close.c -- close database -@item -create.c -- create a table -@item -_dbug.c -- support routines for use with "dbug" (see the \dbug -description) -@item -delete.c -- delete a row -@item -_dynrec.c -- functions to handle space-packed records and blobs -@item -extra.c -- setting options and buffer sizes when optimizing table -handling -@item -info.c -- Information about database status -@item -_key.c -- for handling keys -@item -_locking.c -- lock database -@item -log.c -- save commands in log file which myisamlog program can read -@item -_packrec.c -- compress records -@item -_page.c -- read and write pages containing keys -@item -panic.c -- the mi_panic routine, probably for sudden shutdowns -@item -range.c -- approximate count of how many records lie between two -keys -@item -rfirst.c -- read first row through a specific key (very short) -@item -rkey.c -- read a record using a key -@item -rlast.c -- read last row with same key as previously-read row -@item -rnext.c -- read next row with same key as previously-read row -@item -rprev.c -- read previous row with same key as previously-read row -@item -rrnd.c -- read a row based on position -@item -rsame.c -- find current row using positional read or key-based read -@item -rsamepos.c -- positional read -@item -_search.c -- key-handling functions -@item -static.c -- static variables (very short) -@item -_statrec.c -- functions to handle fixed-length records -@item -test1.c -- testing basic functions -@item -test2.c -- testing database and storing results -@item -test3.c -- testing locking -@item -update.c -- update an existing row -@item -write.c -- insert a new row -@item -pack_isam.c -- pack isam file (NOTE TO SELF ?? equivalent to -\myisam\myisampack.c) -@end itemize -@*@* - -Except for one minor C file (pack_isam.c) every program in the ISAM -directory has a counterpart in the MyISAM directory. For example -\isam\update.c corresponds to \myisam\mi_update.c. However, the -reverse is not true -- there are many files in the MyISAM directory -which have no counterpart in the ISAM directory. -@*@* - -The reason is simple -- it's because the ISAM files are becoming -obsolete. When MySQL programmers add new features, they add them for -MyISAM only. The student can therefore ignore all files in this -directory and study the MyISAM programs instead. -@*@* - @subsection libmysql The MySQL Library, Part 1. @@ -3756,25 +3715,33 @@ sending messages, the client part merely calls the server part. The libmysql files are split into three directories: libmysql (this one), libmysql_r (the next one), and libmysqld (the next one after -that). It may be that the original intention was that the libmysql -directory would hold the "client part" files, and the libmysqld -directory would hold the "server part" files. +that). +@*@* + +The "library of mysql" has some client-connection +modules. For example, as described in an earlier +section of this manual, there is a discussion of +libmysql/libmysql.c which sends packets from the +client to the server. Many of the entries in the +libmysql directory (and in the following libmysqld +directory) are 'symlinks' on Linux, that is, they +are in fact pointers to files in other directories. @*@* The program files on this directory are: @itemize @bullet @item -conf_to_src.c -- has to do with charsets +conf_to_src.c -- has to do with charsets @item -dll.c -- initialization of the dll library +dll.c -- initialization of the dll library @item -errmsg.c -- English error messages, compare \mysys\errors.c +errmsg.c -- English error messages, compare \mysys\errors.c @item -get_password.c -- get password +get_password.c -- get password @item -libmysql.c -- the main "packet-sending emulation" program +libmysql.c -- the code that implements the MySQL API, i.e. the functions a client that wants to connect to MySQL will call @item -manager.c -- initialize/connect/fetch with MySQL manager +manager.c -- initialize/connect/fetch with MySQL manager @end itemize @*@* @@ -3783,8 +3750,7 @@ manager.c -- initialize/connect/fetch with MySQL manager The MySQL Library, Part 2. @*@* -This is a continuation of the libmysql directory. There is only one -file here: +There is only one file here, used to build a thread-safe libmysql library: @itemize @bullet @item makefile.am @@ -3796,83 +3762,27 @@ makefile.am The MySQL library, Part 3. @*@* -This is a continuation of the libmysql directory. The program files on -this directory are: +The Embedded MySQL Server Library. The product of libmysqld +is not a client/server affair, but a library. There is a wrapper +to emulate the client calls. The program files on this directory +are: @itemize @bullet @item -libmysqld.c -- The called side, compare the mysqld.exe source +libmysqld.c -- The called side, compare the mysqld.exe source @item -lib_vio.c -- Emulate the vio directory's communication buffer +lib_vio.c -- Emulate the vio directory's communication buffer @end itemize @*@* @subsection man -Manual pages. -@*@* - -These are not the actual "man" (manual) pages, they are switches for -the production. -@*@* - -@subsection merge - -The MERGE table handler. -@*@* - -For a description of the MERGE table handler, see the MySQL Reference -Manual, section 7.2. -@*@* - -You'll notice that there seem to be several directories with -similar-sounding names of C files in them. That's because the MySQL -table handlers are all quite similar. -@*@* - -The related directories are: -@itemize @bullet -@item -\isam -- for ISAM -@item -\myisam -- for MyISAM -@item -\merge -- for ISAM MERGE (mostly call functions in \isam programs) -@item -\myisammrg -- for MyISAM MERGE (mostly call functions in \myisam -programs) -@end itemize +Some user-contributed manual pages @*@* -To avoid duplication, only the \myisam program versions are discussed. -@*@* - -The C programs in this (merge) directory are: -@itemize @bullet -@item -mrg_close.c -- compare \isam's close.c -@item -mrg_create.c -- "" create.c -@item -mrg_delete.c -- "" delete.c -@item -mrg_extra.c -- "" extra.c -@item -mrg_info.c -- "" info.c -@item -mrg_locking.c -- "" locking.c -@item -mrg_open.c -- "" open.c -@item -mrg_panic.c -- "" panic.c -@item -mrg_rrnd.c -- "" rrnd.c -@item -mrg_rsame.c -- "" rsame.c -@item -mrg_static.c -- "" static.c -@item -mrg_update.c -- "" update.c -@end itemize +These are user-contributed "man" (manual) pages in a special markup +format. The format is described in a document with a heading like +"man page for man" or "macros to format man pages" which you can find +in a Linux directory or on the Internet. @*@* @subsection myisam @@ -3883,23 +3793,17 @@ The MyISAM table handler. The C files in this subdirectory come in six main groups: @itemize @bullet @item -ft*.c files -- ft stands for "Full Text", code contributed by Sergei -Golubchik +ft*.c files -- ft stands for "Full Text", code contributed by Sergei Golubchik @item -mi*.c files -- mi stands for "My Isam", these are the main programs -for Myisam +mi*.c files -- mi stands for "My Isam", these are the main programs for Myisam @item -myisam*.c files -- for example, "myisamchk" utility routine -functions source +myisam*.c files -- for example, "myisamchk" utility routine functions source @item -rt*.c files -- rt stands for "rtree", some code was written by -Alexander Barkov +rt*.c files -- rt stands for "rtree", some code was written by Alexander Barkov @item -sp*.c files -- sp stands for "spatial", some code was written by -Ramil Kalimullin +sp*.c files -- sp stands for "spatial", some code was written by Ramil Kalimullin @item -sort.c -- this is a single file that sorts keys for index-create -purposes +sort.c -- this is a single file that sorts keys for index-create purposes @end itemize @*@* @@ -3910,10 +3814,9 @@ programs. They are: @item mi_cache.c -- for reading records from a cache @item -mi_changed.c -- a single routine for setting a "changed" flag (very -short) +mi_changed.c -- a single routine for setting a "changed" flag (very short) @item -mi_check.c -- doesn't just do checks, ?? for myisamchk program? +mi_check.c -- for checking and repairing tables. Used by the myisamchk program and by the MySQL server. @item mi_checksum.c -- calculates a checksum for a row @item @@ -3921,8 +3824,7 @@ mi_close.c -- close database @item mi_create.c -- create a table @item -mi_dbug.c -- support routines for use with "dbug" (see \dbug -description) +mi_dbug.c -- support routines for use with "dbug" (see \dbug description) @item mi_delete.c -- delete a row @item @@ -3940,58 +3842,57 @@ mi_key.c -- for handling keys @item mi_locking.c -- lock database @item -mi_log.c -- save commands in log file which myisamlog program can read +mi_log.c -- save commands in a log file which myisamlog program can read. Can be used to exactly replay a set of changes to a table. @item mi_open.c -- open database @item mi_packrec.c -- read from a data file compresed with myisampack @item -mi_page.c -- read and write pages containing keys +mi_page.c -- read and write pages containing keys @item -mi_panic.c -- the mi_panic routine, probably for sudden shutdowns +mi_panic.c -- the mi_panic routine, probably for sudden shutdowns @item mi_range.c -- approximate count of how many records lie between two keys @item -mi_rename.c -- rename a table +mi_rename.c -- rename a table @item mi_rfirst.c -- read first row through a specific key (very short) @item -mi_rkey.c -- read a record using a key +mi_rkey.c -- read a record using a key @item -mi_rlast.c -- read last row with same key as previously-read row +mi_rlast.c -- read last row with same key as previously-read row @item -mi_rnext.c -- read next row with same key as previously-read row +mi_rnext.c -- read next row with same key as previously-read row @item -mi_rnext_same.c -- same as mi_rnext.c, but abort if the key changes +mi_rnext_same.c -- same as mi_rnext.c, but abort if the key changes @item mi_rprev.c -- read previous row with same key as previously-read row @item -mi_rrnd.c -- read a row based on position +mi_rrnd.c -- read a row based on position @item -mi_rsame.c -- find current row using positional read or key-based -read +mi_rsame.c -- find current row using positional read or key-based read @item -mi_rsamepos.c -- positional read +mi_rsamepos.c -- positional read @item -mi_scan.c -- read all rows sequentially +mi_scan.c -- read all rows sequentially @item -mi_search.c -- key-handling functions +mi_search.c -- key-handling functions @item mi_static.c -- static variables (very short) @item -mi_statrec.c -- functions to handle fixed-length records +mi_statrec.c -- functions to handle fixed-length records @item -mi_test1.c -- testing basic functions +mi_test1.c -- testing basic functions @item -mi_test2.c -- testing database and storing results +mi_test2.c -- testing database and storing results @item -mi_test3.c -- testing locking +mi_test3.c -- testing locking @item -mi_unique.c -- functions to check if a row is unique +mi_unique.c -- functions to check if a row is unique @item -mi_update.c -- update an existing row +mi_update.c -- update an existing row @item -mi_write.c -- insert a new row +mi_write.c -- insert a new row @end itemize @*@* @@ -4104,7 +4005,7 @@ tests @subsection mysys -MySQL system library (Low level routines for file access etc.). +MySQL system library. Low level routines for file access and so on. @*@* There are 115 *.c programs in this directory: @@ -4112,13 +4013,11 @@ There are 115 *.c programs in this directory: @item array.c -- Dynamic array handling @item -charset.c -- Using dynamic character sets, set default character -set, ... +charset.c -- Using dynamic character sets, set default character set, ... @item -charset2html.c -- Checking what character set a browser is using +charset2html.c -- Check what character set a browser is using @item -checksum.c -- Calculate checksum for a memory block, used for -pack_isam +checksum.c -- Calculate checksum for a memory block, used for pack_isam @item default.c -- Find defaults from *.cnf or *.ini files @item @@ -4128,54 +4027,51 @@ hash.c -- Hash search/compare/free functions "for saving keys" @item list.c -- Double-linked lists @item -make-conf.c -- "Make a charset .conf file out of a ctype-charset.c -file" +make-conf.c -- "Make a charset .conf file out of a ctype-charset.c file" @item md5.c -- MD5 ("Message Digest 5") algorithm from RSA Data Security @item -mf_brkhant.c -- Prevent user from doing a Break during critical -execution +mf_brkhant.c -- Prevent user from doing a Break during critical execution (not used in MySQL; can be used by standalone MyISAM applications) @item -mf_cache.c -- "Open a temporary file and cache it with io_cache" +mf_cache.c -- "Open a temporary file and cache it with io_cache" @item -mf_dirname.c -- Parse/convert directory names +mf_dirname.c -- Parse/convert directory names @item -mf_fn_ext.c -- Get filename extension +mf_fn_ext.c -- Get filename extension @item -mf_format.c -- Format a filename +mf_format.c -- Format a filename @item -mf_getdate.c -- Get date, return in yyyy-mm-dd hh:mm:ss format +mf_getdate.c -- Get date, return in yyyy-mm-dd hh:mm:ss format @item -mf_iocache.c -- Cached read/write of files in fixed-size units +mf_iocache.c -- Cached read/write of files in fixed-size units @item -mf_iocache2.c -- Continuation of mf_iocache.c +mf_iocache2.c -- Continuation of mf_iocache.c @item -mf_keycache.c -- Key block caching for certain file types +mf_keycache.c -- Key block caching for certain file types @item mf_loadpath.c -- Return full path name (no ..\ stuff) @item mf_pack.c -- Packing/unpacking directory names for create purposes @item -mf_path.c -- Determine where a program can find its files +mf_path.c -- Determine where a program can find its files @item -mf_qsort.c -- Quicksort +mf_qsort.c -- Quicksort @item -mf_qsort2.c -- Quicksort, part 2 +mf_qsort2.c -- Quicksort, part 2 (allows the passing of an extra argument to the sort-compare routine) @item -mf_radix.c -- Radix sort +mf_radix.c -- Radix sort @item -mf_same.c -- Determine whether filenames are the same +mf_same.c -- Determine whether filenames are the same @item -mf_sort.c -- Sort with choice of Quicksort or Radix sort +mf_sort.c -- Sort with choice of Quicksort or Radix sort @item -mf_soundex.c -- Soundex algorithm derived from EDN Nov. 14, 1985 -(pg. 36) +mf_soundex.c -- Soundex algorithm derived from EDN Nov. 14, 1985 (pg. 36) @item -mf_strip.c -- Strip trail spaces from a string +mf_strip.c -- Strip trail spaces from a string @item -mf_tempdir.c -- Initialize/find/free temporary directory +mf_tempdir.c -- Initialize/find/free temporary directory @item -mf_tempfile.c -- Create a temporary file +mf_tempfile.c -- Create a temporary file @item mf_unixpath.c -- Convert filename to UNIX-style filename @item @@ -4300,8 +4196,7 @@ my_rename.c -- Rename without delete @item my_seek.c -- Seek, i.e. point to a spot within a file @item -my_semaphore.c -- Semaphore routines, for use on OS that doesn't -support them +my_semaphore.c -- Semaphore routines, for use on OS that doesn't support them @item my_sleep.c -- Wait n microseconds @item @@ -4309,67 +4204,61 @@ my_static.c -- Static variables used by the mysys library @item my_symlink.c -- Read a symbolic link (symlinks are a UNIX thing, I guess) @item -my_symlink2.c -- Part 2 of my_symlink.c +my_symlink2.c -- Part 2 of my_symlink.c @item -my_tempnam.c -- Obsolete temporary-filename routine used by ISAM table handler +my_tempnam.c -- Obsolete temporary-filename routine used by ISAM table handler @item -my_thr_init.c -- initialize/allocate "all mysys & debug thread -variables" +my_thr_init.c -- initialize/allocate "all mysys & debug thread variables" @item -my_wincond.c -- Windows-specific: emulate Posix conditions +my_wincond.c -- Windows-specific: emulate Posix conditions @item -my_winsem.c -- Windows-specific: emulate Posix threads +my_winsem.c -- Windows-specific: emulate Posix threads @item -my_winthread.c -- Windows-specific: emulate Posix threads +my_winthread.c -- Windows-specific: emulate Posix threads @item -my_write.c -- Write a specified number of bytes to a file +my_write.c -- Write a specified number of bytes to a file @item -ptr_cmp.c -- Point to an optimal byte-comparison function +ptr_cmp.c -- Point to an optimal byte-comparison function @item -queues.c -- Handle priority queues as in Robert Sedgewick's book +queues.c -- Handle priority queues as in Robert Sedgewick's book @item raid2.c -- RAID support (the true implementation is in raid.cc) @item -rijndael.c -- "Optimised ANSI C code for the Rijndael cipher (now -AES") +rijndael.c -- "Optimised ANSI C code for the Rijndael cipher (now AES") @item -safemalloc.c -- A version of the standard malloc() with safety -checking +safemalloc.c -- A version of the standard malloc() with safety checking @item -sha1.c -- Implementation of Secure Hashing Algorithm 1 +sha1.c -- Implementation of Secure Hashing Algorithm 1 @item -string.c -- Initialize/append/free dynamically-sized strings +string.c -- Initialize/append/free dynamically-sized strings; see also sql_string.cc in the /sql directory @item -testhash.c -- Standalone program: test the hash library routines +testhash.c -- Standalone program: test the hash library routines @item -test_charset.c -- Standalone program: display character set -information +test_charset.c -- Standalone program: display character set information @item -test_dir.c -- Standalone program: placeholder for "test all -functions" idea +test_dir.c -- Standalone program: placeholder for "test all functions" idea @item -test_fn.c -- Standalone program: apparently tests a function +test_fn.c -- Standalone program: apparently tests a function @item -test_xml.c -- Standalone program: test XML routines +test_xml.c -- Standalone program: test XML routines @item -thr_alarm.c -- Thread alarms and signal handling +thr_alarm.c -- Thread alarms and signal handling @item -thr_lock.c -- "Read and write locks for Posix threads" +thr_lock.c -- "Read and write locks for Posix threads" @item -thr_mutex.c -- A wrapper for mutex functions +thr_mutex.c -- A wrapper for mutex functions @item -thr_rwlock.c -- Synchronizes the readers' thread locks with the -writer's lock +thr_rwlock.c -- Synchronizes the readers' thread locks with the writer's lock @item -tree.c -- Initialize/search/free binary trees +tree.c -- Initialize/search/free binary trees @item -typelib.c -- Determine what type a field has +typelib.c -- Find a string in a set of strings; returns the offset to the string found @end itemize @*@* You can find documentation for the main functions in these files -elsewhere in this document. -For example, the main functions in my_getwd.c are described thus: +elsewhere in this document. For example, the main functions in my_getwd.c +are described thus: @*@* @example @@ -4399,15 +4288,15 @@ testing. These are the five *.c files, all from Novell Inc.: @itemize @bullet @item -libmysqlmain.c -- Only one function: init_available_charsets() +libmysqlmain.c -- Only one function: init_available_charsets() @item -my_manage.c -- Standalone management utility +my_manage.c -- Standalone management utility @item -mysql_install_db.c -- Compare \scripts\mysql_install_db.sh +mysql_install_db.c -- Compare \scripts\mysql_install_db.sh @item -mysql_test_run.c -- Short test program +mysql_test_run.c -- Short test program @item -mysqld_safe.c -- Compare \scripts\mysqld_safe.sh +mysqld_safe.c -- Compare \scripts\mysqld_safe.sh @end itemize Perhaps the most important file is: @@ -4419,16 +4308,16 @@ netware.patch -- NetWare-specific build instructions and switches @*@* For instructions about basic installation, see "Deployment Guide For -NetWare AMP" at: +NetWare AMP" at: @url{http://developer.novell.com/ndk/whitepapers/namp.htm} @* @subsection NEW-RPMS -New "RPM Package Manager" files. +Directory to place RPMs while making a distribution. @*@* -This directory is not part of the Windows distribution. It is +This directory is not part of the Windows distribution. It is a temporary directory used during RPM builds with Linux distributions. @*@* @@ -4442,10 +4331,10 @@ people from outside MySQL: Yuri Dario, Timo Maier, and John M Alfredsson. There are no .C program files in this directory. @*@* -The contents of \os2 are: +The contents of \os2 are: @itemize @bullet @item -A Readme.Txt file +A Readme.Txt file @item An \include subdirectory containing .h files which are for OS/2 only @item @@ -4460,7 +4349,7 @@ there have been no updates for MySQL 4.0 for this section. @subsection pstack -Process stack display. +Process stack display (not currently used). @*@* This is a set of publicly-available debugging aids which all do pretty @@ -4478,7 +4367,7 @@ and it crashes. @subsection regex -Regular Expression library for support of REGEXP function. +Henry Spencer's Regular Expression library for support of REGEXP function. @*@* This is the copyrighted product of Henry Spencer from the University @@ -4504,7 +4393,7 @@ This program calls the 'regcomp' function, which is the entry point in @subsection SCCS -Source Code Control System. +Source Code Control System (not part of source distribution). @*@* You will see this directory if and only if you used BitKeeper for @@ -4514,10 +4403,10 @@ administration and are not of interest to application programmers. @subsection scripts -SQL batches, e.g. for converting msql to MySQL. +SQL batches, e.g. mysqlbug and mysql_install_db. @*@* -The *.sh filename extension stands for "shell script". Linux +The *.sh filename extension stands for "shell script". Linux programmers use it where Windows programmers would use a *.bat (batch filename extension). @*@* @@ -4525,23 +4414,23 @@ programmers use it where Windows programmers would use a *.bat The *.sh files on this directory are: @itemize @bullet @item -fill_help_tables.sh -- Create help-information tables and insert +fill_help_tables.sh -- Create help-information tables and insert @item make_binary_distribution.sh -- Get configure information, make, produce tar @item -msql2mysql.sh -- Convert mSQL programs and scripts to MySQL, partly +msql2mysql.sh -- Convert (partly) mSQL programs and scripts to MySQL @item -mysqlbug.sh -- Create a bug report and mail it +mysqlbug.sh -- Create a bug report and mail it @item -mysqld_multi.sh -- Start/stop any number of mysqld instances +mysqld_multi.sh -- Start/stop any number of mysqld instances @item -mysqld_safe-watch.sh -- Start/restart in safe mode +mysqld_safe-watch.sh -- Start/restart in safe mode @item -mysqld_safe.sh -- Start/restart in safe mode +mysqld_safe.sh -- Start/restart in safe mode @item -mysqldumpslow.sh -- Parse and summarize the slow query log +mysqldumpslow.sh -- Parse and summarize the slow query log @item -mysqlhotcopy.sh -- Hot backup +mysqlhotcopy.sh -- Hot backup @item mysql_config.sh -- Get configuration information that might be needed to compile a client @item @@ -4553,15 +4442,14 @@ mysql_find_rows.sh -- Search for queries containing <regexp> @item mysql_fix_extensions.sh -- Renames some file extensions, not recommended @item -mysql_fix_privilege_tables.sh -- Fix mysql.user etc. if upgrading to MySQL 3.23.14+ +mysql_fix_privilege_tables.sh -- Fix mysql.user etc. when upgrading. Can be safely run during any upgrade to get the newest +MySQL privilege tables @item mysql_install_db.sh -- Create privilege tables and func table @item -mysql_secure_installation.sh -- Disallow remote root login, -eliminate test, etc. +mysql_secure_installation.sh -- Disallow remote root login, eliminate test, etc. @item -mysql_setpermission.sh -- Aid to add users or databases, sets -privileges +mysql_setpermission.sh -- Aid to add users or databases, sets privileges @item mysql_tableinfo.sh -- Puts info re MySQL tables into a MySQL table @item @@ -4577,91 +4465,90 @@ Programs for handling SQL commands. The "core" of MySQL. These are the .c and .cc files in the sql directory: @itemize @bullet @item -cache_manager.cc -- manages a number of blocks -@item -convert.cc -- convert tables between different character sets +convert.cc -- convert tables between different character sets @item -derror.cc -- read language-dependent message file +derror.cc -- read language-dependent message file @item -des_key_file.cc -- load DES keys from plaintext file +des_key_file.cc -- load DES keys from plaintext file @item -field.cc -- "implement classes defined in field.h" (long) +field.cc -- "implement classes defined in field.h" (long); defines all storage methods MySQL uses to store field information +into records that are then passed to handlers @item field_conv.cc -- functions to copy data between fields @item filesort.cc -- sort a result set, using memory or temporary files @item -frm_crypt.cc -- contains only one short function: get_crypt_for_frm +frm_crypt.cc -- contains only one short function: get_crypt_for_frm @item -gen_lex_hash.cc -- Knuth's algorithm from Vol 3 Sorting and Searching, Chapter 6.3 +gen_lex_hash.cc -- Knuth's algorithm from Vol 3 Sorting and Searching, Chapter 6.3; used to search for SQL keywords in a query @item gstream.cc -- GTextReadStream, used to read GIS objects @item -handler.cc -- handler-calling functions +handler.cc -- handler-calling functions @item -hash_filo.cc -- static-sized hash tables +hash_filo.cc -- static-sized hash tables, used to store info like hostname -> ip tables in a FIFO manner @item -ha_berkeley.cc -- Handler: BDB +ha_berkeley.cc -- Handler: BDB @item -ha_heap.cc -- Handler: Heap +ha_heap.cc -- Handler: Heap @item -ha_innodb.cc -- Handler: InnoDB +ha_innodb.cc -- Handler: InnoDB @item -ha_isam.cc -- Handler: ISAM +ha_isam.cc -- Handler: ISAM @item ha_isammrg.cc -- Handler: (ISAM MERGE) @item -ha_myisam.cc -- Handler: MyISAM +ha_myisam.cc -- Handler: MyISAM @item ha_myisammrg.cc -- Handler: (MyISAM MERGE) @item -hostname.cc -- Given IP, return hostname +hostname.cc -- Given IP, return hostname @item -init.cc -- Init and dummy functions for interface with unireg +init.cc -- Init and dummy functions for interface with unireg @item -item.cc -- Item functions +item.cc -- Item functions @item -item_buff.cc -- Buffers to save and compare item values +item_buff.cc -- Buffers to save and compare item values @item -item_cmpfunc.cc -- Definition of all compare functions +item_cmpfunc.cc -- Definition of all compare functions @item -item_create.cc -- Create an item. Used by lex.h. +item_create.cc -- Create an item. Used by lex.h. @item -item_func.cc -- Numerical functions +item_func.cc -- Numerical functions @item -item_row.cc -- Row items for comparing rows and for IN on rows +item_row.cc -- Row items for comparing rows and for IN on rows @item item_sum.cc -- Set functions (SUM, AVG, etc.) @item -item_strfunc.cc -- String functions +item_strfunc.cc -- String functions @item -item_subselect.cc -- Item subselect +item_subselect.cc -- Item subselect @item -item_timefunc.cc -- Date/time functions, e.g. week of year +item_timefunc.cc -- Date/time functions, e.g. week of year @item item_uniq.cc -- Empty file, here for compatibility reasons @item -key.cc -- Functions to handle keys and fields in forms +key.cc -- Functions to create keys from records and compare a key to a key in a record @item -lock.cc -- Locks +lock.cc -- Locks @item -log.cc -- Logs +log.cc -- Logs @item -log_event.cc -- Log event +log_event.cc -- Log event (a binary log consists of a stream of log events) @item -matherr.c -- Handling overflow, underflow, etc. +matherr.c -- Handling overflow, underflow, etc. @item mf_iocache.cc -- Caching of (sequential) reads and writes @item -mini_client.cc -- Client included in server for server-server messaging +mini_client.cc -- Client included in server for server-server messaging; used by the replication code @item -mysqld.cc -- Source of mysqld.exe +mysqld.cc -- Source of mysqld.exe; includes the main() program that starts mysqld, handling of signals and connections @item -my_lock.c -- Lock part of a file +my_lock.c -- Lock part of a file (like /mysys/my_lock.c, but with timeout handling for threads) @item -net_serv.cc -- Read/write of packets on a network socket +net_serv.cc -- Read/write of packets on a network socket @item -nt_servc.cc -- Initialize/register/remove an NT service +nt_servc.cc -- Initialize/register/remove an NT service @item opt_ft.cc -- Create a FT or QUICK RANGE based on a key (very short) @item @@ -4671,9 +4558,9 @@ opt_sum.cc -- Optimize functions in presence of (implied) GROUP BY @item password.c -- Password checking @item -procedure.cc -- Procedure +procedure.cc -- Procedure interface, as used in SELECT * FROM Table_name PROCEDURE ANALYSE @item -protocol.cc -- Low level functions for storing data to be sent to client +protocol.cc -- Low level functions for PACKING data that is sent to client; actual sending done with net_serv.cc @item records.cc -- Functions for easy reading of records, possible through a cache @item @@ -4685,15 +4572,15 @@ slave.cc -- Procedures for a slave in a master/slave (replication) relation @item spatial.cc -- Geometry stuff (lines, points, etc.) @item -sql_acl.cc -- Functions related to ACL security +sql_acl.cc -- Functions related to ACL security; checks, stores, retrieves, and deletes MySQL user level privileges @item -sql_analyse.cc -- Analyse an input string (?) +sql_analyse.cc -- Implements the PROCEDURE analyse, which analyses a query result and returns the 'optimal' data type for each result column @item -sql_base.cc -- Basic functions needed by many modules +sql_base.cc -- Basic functions needed by many modules, like opening and closing tables with table cache management @item sql_cache.cc -- SQL query cache, with long comments about how caching works @item -sql_class.cc -- SQL class +sql_class.cc -- SQL class; implements the SQL base classes, of which THD (THREAD object) is the most important @item sql_crypt.cc -- Encode / decode, very short @item @@ -4707,63 +4594,62 @@ sql_do.cc -- The DO statement @item sql_error.cc -- Errors and warnings @item -sql_handler.cc -- Direct access to ISAM +sql_handler.cc -- Implements the HANDLER interface, which gives direct access to rows in MyISAM and InnoDB @item -sql_help.cc -- The HELP statement (if there is one?) +sql_help.cc -- The HELP statement @item sql_insert.cc -- The INSERT statement @item -sql_lex.cc -- Related to lex or yacc +sql_lex.cc -- Does lexical analysis of a query; i.e. breaks a query string into pieces and determines the basic type (number, +string, keyword, etc.) of each piece @item -sql_list.cc -- Only list_node_end_of_list, short +sql_list.cc -- Only list_node_end_of_list, short (the rest of the list class is implemented in sql_list.h) @item -sql_load.cc -- The LOAD DATA statement? +sql_load.cc -- The LOAD DATA statement @item -sql_map.cc -- Memory-mapped files? +sql_map.cc -- Memory-mapped files (not yet in use) @item -sql_manager.cc -- Maintenance tasks, e.g. flushing the buffers -periodically +sql_manager.cc -- Maintenance tasks, e.g. flushing the buffers periodically; used with BDB table logs @item -sql_olap.cc -- ROLLUP +sql_olap.cc -- ROLLUP @item -sql_parse.cc -- Parse an SQL statement +sql_parse.cc -- Parse an SQL statement; do initial checks and then jump to the function that should execute the statement @item -sql_prepare.cc -- Prepare an SQL statement +sql_prepare.cc -- Prepare an SQL statement, or use a prepared statement @item -sql_repl.cc -- Replication +sql_repl.cc -- Replication @item -sql_rename.cc -- Rename table +sql_rename.cc -- Rename table @item -sql_select.cc -- Select and join optimisation +sql_select.cc -- Select and join optimisation @item -sql_show.cc -- The SHOW statement +sql_show.cc -- The SHOW statement @item -sql_string.cc -- String functions: alloc, realloc, copy, convert, -etc. +sql_string.cc -- String functions: alloc, realloc, copy, convert, etc. @item -sql_table.cc -- The DROP TABLE and ALTER TABLE statements +sql_table.cc -- The DROP TABLE and ALTER TABLE statements @item -sql_test.cc -- Some debugging information +sql_test.cc -- Some debugging information @item -sql_udf.cc -- User-defined functions +sql_udf.cc -- User-defined functions @item -sql_union.cc -- The UNION operator +sql_union.cc -- The UNION operator @item -sql_update.cc -- The UPDATE statement +sql_update.cc -- The UPDATE statement @item -stacktrace.c -- Display stack trace (Linux/Intel only?) +stacktrace.c -- Display stack trace (Linux/Intel only) @item -table.cc -- Table metadata retrieval, mostly +table.cc -- Table metadata retrieval; read the table definition from a .frm file and store it in a TABLE object @item -thr_malloc.cc -- Mallocs used in threads +thr_malloc.cc -- Thread-safe interface to /mysys/my_alloc.c @item -time.cc -- Date and time functions +time.cc -- Date and time functions @item -udf_example.cc -- Example file of user-defined functions +udf_example.cc -- Example file of user-defined functions @item -uniques.cc -- Function to handle quick removal of duplicates +uniques.cc -- Function to handle quick removal of duplicates @item -unireg.cc -- Create a unireg form file from a FIELD and field-info struct +unireg.cc -- Create a unireg form file (.frm) from a FIELD and field-info struct @end itemize @*@* @@ -4781,17 +4667,15 @@ available all the material necessary to reproduce all the tests. There are five subdirectories and sub-subdirectories: @itemize @bullet @item -\Comments -- Comments about results from tests of Access, Adabas, -etc. +\Comments -- Comments about results from tests of Access, Adabas, etc. @item -\Data\ATIS -- .txt files containing input data for the "ATIS" tests +\Data\ATIS -- .txt files containing input data for the "ATIS" tests @item -\Data\Wisconsin -- .txt files containing input data for the -"Wisconsin" tests +\Data\Wisconsin -- .txt files containing input data for the "Wisconsin" tests @item -\Results -- old test results +\Results -- old test results @item -\Results-win32 -- old test results from Windows 32-bit tests +\Results-win32 -- old test results from Windows 32-bit tests @end itemize @*@* @@ -4807,7 +4691,8 @@ There is one README file and one TODO file. @subsection SSL -Secure Sockets Layer. +Secure Sockets Layer; includes an example certification one can use +test an SSL (secure) database connection. @*@* This isn't a code directory. It contains a short note from Tonu Samuel @@ -4836,7 +4721,7 @@ recent Pentium class processors, though. The .C files are: @itemize @bullet @item -atof.c -- ascii-to-float, MySQL version +atof.c -- ascii-to-float, MySQL version @item bchange.c -- short replacement routine written by Monty Widenius in 1987 @@ -4858,8 +4743,7 @@ bmove_upp.c -- bmove.c variant, starting with last byte @item bzero.c -- something like bfill with an argument of 0 @item -conf_to_src.c -- reading a configuration file (NOTE TO SELF ? what's -this doing here?) +conf_to_src.c -- reading a configuration file @item ctype*.c -- string handling programs for each char type MySQL handles @@ -4885,7 +4769,7 @@ r_strinstr.c -- see if one string is within another @item str2int.c -- convert string to integer @item -strappend.c -- append one string to another +strappend.c -- fill up a string to n characters @item strcat.c -- concatenate strings @item @@ -4905,11 +4789,11 @@ strinstr.c -- find string within string @item strlen.c -- return length of string in bytes @item -strmake.c -- move n characters, or move till end +strmake.c -- create new string from old string with fixed length, append end \0 if needed @item -strmov.c -- move source to dest and return pointer to end +strmov.c -- move source to dest and return pointer to end @item -strnlen.c -- return length of string, or return n +strnlen.c -- return min(length of string, n) @item strnmov.c -- move source to dest for source size, or for n bytes @item @@ -4933,9 +4817,9 @@ strxnmov.c -- like strxmov.c but with a maximum length n @item str_test.c -- test of all the string functions encoded in assembler @item -udiv.c -- unsigned long divide +udiv.c -- unsigned long divide, for operating systems that don't support these @item -xml.c -- read and parse XML strings +xml.c -- read and parse XML strings; used to read character definition information stored in /sql/share/charsets @end itemize @*@* @@ -4947,21 +4831,41 @@ members of the Intel processor family. @subsection support-files -Support files. +Files used to build MySQL on different systems. @*@* The files here are for building ("making") MySQL given a package manager, compiler, linker, and other build tools. The support files -provide instructions and switches for the build processes. +provide instructions and switches for the build processes. They +include example my.cnf files one can use as a default setup for +MySQL. @*@* @subsection tests -Tests in Perl. +Tests in Perl and in C. @*@* -These are tests that were run once to check for bugs in various -scenarios: forks, locks, big records, exporting, truncating, etc. +The files in this directory are test programs that can be used +as a base to write a program to simulate problems in MySQL in various +scenarios: forks, locks, big records, exporting, truncating, and so on. +Some examples are: +@itemize @bullet +@item +connect_test.c -- test that a connect is possible +@item +insert_test.c -- test that an insert is possible +@item +list_test.c -- test that a select is possible +@item +select_test.c -- test that a select is possible +@item +showdb_test.c -- test that a show-databases is possible +@item +ssl_test.c -- test that SSL is possible +@item +thread_test.c -- test that threading is possible +@end itemize @*@* @subsection tools @@ -4972,7 +4876,9 @@ Tools -- well, actually, one tool. The only file is: @itemize @bullet @item -mysqlmanager.c -- A "server management daemon" by Sasha Pachev +mysqlmanager.c -- A "server management daemon" by Sasha Pachev. This +is a tool under development and is not yet useful. Related to fail-safe +replication. @end itemize @*@* @@ -4984,11 +4890,16 @@ Visual C++ Files. Includes this entire directory, repeated for VC++ (Windows) use. @*@* -VC++Files has subdirectories which are copies of the main directories. -For example there is a subdirectory \VC++Files\heap, which has the -same files as \heap. So for a description of the files in -\VC++Files\heap, see the description of the files in \heap. The same -applies for almost all of VC++Files's subdirectories (bdb, client, +VC++Files includes a complete environment to compile MySQL with the VC++ +compiler. To use it, just copy the files on this directory; the make_win_src_distribution.sh +script uses these files to create a Windows source installation. +@*@* + +This directory has subdirectories which are copies of the main directories. +For example, there is a subdirectory \VC++Files\heap, which has the Microsoft +developer studio project file to compile \heap with VC++. So for a description +of the files in \VC++Files\heap, see the description of the files in \heap. The +same applies for almost all of VC++Files's subdirectories (bdb, client, isam, libmysql, etc.). The difference is that the \VC++Files variants are specifically for compilation with Microsoft Visual C++ in 32-bit Windows environments. @@ -4999,54 +4910,60 @@ directories", VC++Files contains these subdirectories, which are not duplicates: @itemize @bullet @item -comp_err -- (nearly empty) +comp_err -- (nearly empty) @item -contrib -- (nearly empty) +contrib -- (nearly empty) @item -InstallShield script files +InstallShield -- script files @item -isamchk -- (nearly empty) +isamchk -- (nearly empty) @item -libmysqltest -- one small non-MySQL test program: mytest.c +libmysqltest -- one small non-MySQL test program: mytest.c @item -myisamchk -- (nearly empty) +myisamchk -- (nearly empty) @item -myisamlog -- (nearly empty) +myisamlog -- (nearly empty) @item -myisammrg -- (nearly empty) +myisammrg -- (nearly empty) @item -mysqlbinlog -- (nearly empty) +mysqlbinlog -- (nearly empty) @item -mysqlmanager -- MFC foundation class files created by AppWizard +mysqlmanager -- MFC foundation class files created by AppWizard @item -mysqlserver -- (nearly empty) +mysqlserver -- (nearly empty) @item -mysqlshutdown -- one short program, mysqlshutdown.c +mysqlshutdown -- one short program, mysqlshutdown.c @item -mysqlwatch.c -- Windows service initialization and monitoring +mysqlwatch.c -- Windows service initialization and monitoring @item -my_print_defaults -- (nearly empty) +my_print_defaults -- (nearly empty) @item -pack_isam -- (nearly empty) +pack_isam -- (nearly empty) @item -perror -- (nearly empty) +perror -- (nearly empty) @item -prepare -- (nearly empty) +prepare -- (nearly empty) @item -replace -- (nearly empty) +replace -- (nearly empty) @item -SCCS -- source code control system +SCCS -- source code control system @item -test1 -- tests connecting via X threads +test1 -- tests connecting via X threads @item -thr_insert_test -- (nearly empty) +thr_insert_test -- (nearly empty) @item thr_test -- one short program used to test for memory-allocation bug @item -winmysqladmin -- the winmysqladmin.exe source. machine-generated? +winmysqladmin -- the winmysqladmin.exe source @end itemize @*@* +The "nearly empty" subdirectories noted above (e.g. comp_err and isamchk) +are needed because VC++ requires one directory per project (i.e. executable). +We are trying to keep to the MySQL standard source layout and compile only +to different directories. +@*@* + @subsection vio Virtual I/O Library. @@ -5094,7 +5011,12 @@ obsolete. @subsection zlib -Data compression library. +Data compression library, used on Windows. +@*@* + +zlib is a data compression library used to support the compressed +protocol and the COMPRESS/UNCOMPRESS functions under Windows. +On Unix, MySQL uses the system libgz.a library for this purpose. @*@* Zlib -- which presumably stands for "Zip Library" -- is not a MySQL @@ -5104,11 +5026,11 @@ variation of the famous "Lempel-Ziv" method, which is also used by bytes is as follows: @itemize @bullet @item -Find a substring which occurs twice in the string. +Find a substring which occurs twice in the string. @item Replace the second occurrence of the substring with (a) a pointer to the first occurrence, plus (b) an indication of the length of the -first occurrence. +first occurrence. @end itemize There is a full description of the library's functions in the gzip @@ -5117,11 +5039,11 @@ manual at: @* There is therefore no need to list the modules in this document. @*@* -The MySQL program that uses zlib is \mysys\my_compress.c. The use is -for packet compression. The client sends messages to the server which -are compressed by zlib. See also: \sql\net_serv.cc. +The MySQL program \mysys\my_compress.c uses zlib for packet compression. +The client sends messages to the server which are compressed by zlib. +See also: \sql\net_serv.cc. -@node Files in InnoDB Sources,,Files in MySQL Sources,Top +@node Files in InnoDB Sources, , Files in MySQL Sources, Top @chapter Annotated List Of Files in the InnoDB Source Code Distribution ERRATUM BY HEIKKI TUURI (START) diff --git a/VC++Files/libmysql/libmysql.dsp b/VC++Files/libmysql/libmysql.dsp index bddf1988e03..43dee62061f 100644 --- a/VC++Files/libmysql/libmysql.dsp +++ b/VC++Files/libmysql/libmysql.dsp @@ -25,7 +25,7 @@ CFG=libmysql - Win32 Debug # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" -CPP=cl.exe +CPP=xicl6.exe MTL=midl.exe RSC=rc.exe @@ -52,14 +52,14 @@ RSC=rc.exe BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo -LINK32=link.exe +LINK32=xilink6.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 # ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /def:"libmysql.def" /out:"..\lib_release\libmysql.dll" /libpath:"." /libpath:"..\lib_release" # SUBTRACT LINK32 /pdb:none # Begin Special Build Tool SOURCE="$(InputPath)" -PostBuild_Desc=Copy .lib file -PostBuild_Cmds=xcopy release\libmysql.lib ..\lib_release\ +PostBuild_Desc=Move DLL export lib +PostBuild_Cmds=xcopy release\libmysql.lib ..\lib_release /y # End Special Build Tool !ELSEIF "$(CFG)" == "libmysql - Win32 Debug" @@ -85,14 +85,14 @@ PostBuild_Cmds=xcopy release\libmysql.lib ..\lib_release\ BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo -LINK32=link.exe +LINK32=xilink6.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 zlib.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /incremental:no /map /debug /machine:I386 /def:"libmysql.def" /out:"..\lib_debug\libmysql.dll" /pdbtype:sept /libpath:"." /libpath:"..\lib_debug" # SUBTRACT LINK32 /pdb:none # Begin Special Build Tool SOURCE="$(InputPath)" -PostBuild_Desc=Copy .lib file -PostBuild_Cmds=xcopy ..\lib_debug\libmysql.dll C:\winnt\system32\ xcopy debug\libmysql.lib ..\lib_debug\ +PostBuild_Desc=Move DLL export lib +PostBuild_Cmds=xcopy ..\lib_debug\libmysql.dll C:\winnt\system32\ /y xcopy debug\libmysql.lib ..\lib_debug\ /y # End Special Build Tool !ENDIF @@ -239,6 +239,10 @@ SOURCE=..\mysys\mf_pack.c # End Source File # Begin Source File +SOURCE=..\mysys\mf_path.c +# End Source File +# Begin Source File + SOURCE=..\mysys\mf_unixpath.c # End Source File # Begin Source File @@ -395,6 +399,10 @@ SOURCE=..\client\select_test.c # End Source File # Begin Source File +SOURCE=..\mysys\sha1.c +# End Source File +# Begin Source File + SOURCE=..\client\sql_string.cpp # End Source File # Begin Source File diff --git a/VC++Files/mysql.dsw b/VC++Files/mysql.dsw index eef82588fa8..9903c91ba1b 100644 --- a/VC++Files/mysql.dsw +++ b/VC++Files/mysql.dsw @@ -605,6 +605,9 @@ Package=<5> Package=<4> {{{ + Begin Project Dependency + Project_Dep_Name strings + End Project Dependency }}} ############################################################################### diff --git a/acinclude.m4 b/acinclude.m4 index cf0233fa38f..4d7900acc3d 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -38,7 +38,7 @@ AC_LANG_SAVE AC_LANG_CPLUSPLUS if test "$ac_cv_prog_gxx" = "yes" then - CXXFLAGS="$CXXFLAGS -Werror" + CXXFLAGS=`echo $CXXFLAGS -Werror | sed 's/-fbranch-probabilities//'` fi mysql_cv_btype_last_arg_accept=none [AC_TRY_COMPILE([#if defined(inline) diff --git a/configure.in b/configure.in index aea415a13c4..a1ea566435b 100644 --- a/configure.in +++ b/configure.in @@ -1862,7 +1862,7 @@ AC_LANG_SAVE AC_LANG_CPLUSPLUS if test "$ac_cv_prog_gxx" = "yes" -a "$with_other_libc" = "no" then - CXXFLAGS="$CXXFLAGS -Werror" + CXXFLAGS=`echo "$CXXFLAGS -Werror" | sed 's/-fbranch-probabilities//'` fi AC_TRY_COMPILE( [#undef inline @@ -1894,7 +1894,7 @@ AC_LANG_SAVE AC_LANG_CPLUSPLUS if test "$ac_cv_prog_gxx" = "yes" -a "$with_other_libc" = "no" then - CXXFLAGS="$CXXFLAGS -Werror" + CXXFLAGS=`echo "$CXXFLAGS -Werror" | sed 's/-fbranch-probabilities//'` fi AC_TRY_COMPILE( [#undef inline @@ -2341,7 +2341,7 @@ extern int mbcharlen_${c}(uint);" mbcharlen_${c}" else CHARSET_COMP_CS_INIT="$CHARSET_COMP_CS_INIT - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL /* mbcharlen */" diff --git a/include/my_global.h b/include/my_global.h index e12a7d7273b..98034fc1cff 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -267,6 +267,10 @@ C_MODE_END #include <asm/atomic.h> #endif #include <errno.h> /* Recommended by debian */ +/* We need the following to go around a problem with openssl on solaris */ +#if defined(HAVE_CRYPT_H) +#include <crypt.h> +#endif /* Go around some bugs in different OS and compilers */ #if defined(_HPUX_SOURCE) && defined(HAVE_SYS_STREAM_H) diff --git a/include/my_pthread.h b/include/my_pthread.h index 0b41dc18fe1..4247b951d82 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -247,6 +247,11 @@ extern int my_sigwait(const sigset_t *set,int *sig); #error Requires at least rev 2 of EMX pthreads library. #endif +#ifdef __NETWARE__ +void my_pthread_exit(void *status); +#define pthread_exit(A) my_pthread_exit(A) +#endif + extern int my_pthread_getprio(pthread_t thread_id); #define pthread_key(T,V) pthread_key_t V diff --git a/include/violite.h b/include/violite.h index a328e51253a..d20fab23239 100644 --- a/include/violite.h +++ b/include/violite.h @@ -148,7 +148,7 @@ my_bool vio_ssl_should_retry(Vio* vio); int vio_ssl_close(Vio* vio); /* Return last error number */ int vio_ssl_errno(Vio *vio); -my_bool vio_ssl_peer_addr(Vio* vio, char *buf); +my_bool vio_ssl_peer_addr(Vio* vio, char *buf, uint16 *port); void vio_ssl_in_addr(Vio *vio, struct in_addr *in); int vio_ssl_blocking(Vio * vio, my_bool set_blocking_mode, my_bool *old_mode); @@ -224,7 +224,7 @@ struct st_vio my_bool (*is_blocking)(Vio*); int (*viokeepalive)(Vio*, my_bool); int (*fastsend)(Vio*); - my_bool (*peer_addr)(Vio*, gptr, uint16*); + my_bool (*peer_addr)(Vio*, char *, uint16*); void (*in_addr)(Vio*, struct in_addr*); my_bool (*should_retry)(Vio*); int (*vioclose)(Vio*); diff --git a/innobase/include/trx0trx.h b/innobase/include/trx0trx.h index 34f820f03e7..be96519c4ea 100644 --- a/innobase/include/trx0trx.h +++ b/innobase/include/trx0trx.h @@ -418,10 +418,6 @@ struct trx_struct{ lock_t* auto_inc_lock; /* possible auto-inc lock reserved by the transaction; note that it is also in the lock list trx_locks */ - ibool ignore_duplicates_in_insert; - /* in an insert roll back only insert - of the latest row in case - of a duplicate key error */ UT_LIST_NODE_T(trx_t) trx_list; /* list of transactions */ UT_LIST_NODE_T(trx_t) diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 20e7514a4ea..ec0546f8c66 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -1439,7 +1439,9 @@ innobase_start_or_create_for_mysql(void) fprintf(stderr, "InnoDB: !!! innodb_force_recovery is set to %lu !!!\n", srv_force_recovery); - } + } + + fflush(stderr); return((int) DB_SUCCESS); } diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c index 38d15866769..4ce2236f78a 100644 --- a/innobase/trx/trx0trx.c +++ b/innobase/trx/trx0trx.c @@ -102,8 +102,6 @@ trx_create( trx->mysql_master_log_file_name = (char*) ""; trx->mysql_master_log_pos = 0; - trx->ignore_duplicates_in_insert = FALSE; - mutex_create(&(trx->undo_mutex)); mutex_set_level(&(trx->undo_mutex), SYNC_TRX_UNDO); diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c index 3fba238a8bf..782731d4765 100644 --- a/libmysqld/libmysqld.c +++ b/libmysqld/libmysqld.c @@ -62,7 +62,7 @@ my_string mysql_unix_port=0; #define closesocket(A) close(A) #endif -static void mysql_once_init(void); +static void mysqld_once_init(void); static MYSQL_DATA *read_rows (MYSQL *mysql,MYSQL_FIELD *fields, uint field_count); static int read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, @@ -729,7 +729,7 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths) MYSQL * STDCALL mysql_init(MYSQL *mysql) { - mysql_once_init(); + mysqld_once_init(); if (!mysql) { if (!(mysql=(MYSQL*) my_malloc(sizeof(*mysql),MYF(MY_WME | MY_ZEROFILL)))) @@ -743,7 +743,7 @@ mysql_init(MYSQL *mysql) } -static void mysql_once_init() +static void mysqld_once_init() { if (!mysql_client_init) { diff --git a/myisam/mi_key.c b/myisam/mi_key.c index 9ec1ca99e0e..5b167cc9ab0 100644 --- a/myisam/mi_key.c +++ b/myisam/mi_key.c @@ -136,11 +136,26 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key, } /* _mi_make_key */ - /* Pack a key to intern format from given format (c_rkey) */ - /* returns length of packed key */ +/* + Pack a key to intern format from given format (c_rkey) + + SYNOPSIS + _mi_pack_key() + info MyISAM handler + uint keynr key number + key Store packed key here + old Not packed key + k_length Length of 'old' to use + last_used_keyseg out parameter. May be NULL + + RETURN + length of packed key + + last_use_keyseg Store pointer to the keyseg after the last used one +*/ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old, - uint k_length) + uint k_length, MI_KEYSEG **last_used_keyseg) { uint length; uchar *pos,*end,*start_key=key; @@ -211,6 +226,8 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old, key+= length; k_length-=length; } + if (last_used_keyseg) + *last_used_keyseg= keyseg; #ifdef NOT_USED if (keyseg->type) diff --git a/myisam/mi_open.c b/myisam/mi_open.c index 2f3ef872492..0ccc8a3bf40 100644 --- a/myisam/mi_open.c +++ b/myisam/mi_open.c @@ -183,8 +183,11 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) share->state_diff_length=len-MI_STATE_INFO_SIZE; if (share->state.header.fulltext_keys) - fprintf(stderr, "Table file %s was created in MySQL 4.1+, use REPAIR TABLE ... USE_FRM to recreate it as a valid MySQL 4.0 table\n", name_buff); - + { + /* Not supported in this version */ + my_errno= HA_ERR_UNSUPPORTED; + goto err; + } mi_state_info_read(disk_cache, &share->state); len= mi_uint2korr(share->state.header.base_info_length); if (len != MI_BASE_INFO_SIZE) diff --git a/myisam/mi_range.c b/myisam/mi_range.c index 70694bf4620..8e85afc5f80 100644 --- a/myisam/mi_range.c +++ b/myisam/mi_range.c @@ -83,7 +83,8 @@ static ha_rows _mi_record_pos(MI_INFO *info, const byte *key, uint key_len, if (key_len == 0) key_len=USE_WHOLE_KEY; key_buff=info->lastkey+info->s->base.max_key_length; - key_len=_mi_pack_key(info,inx,key_buff,(uchar*) key,key_len); + key_len=_mi_pack_key(info,inx,key_buff,(uchar*) key,key_len, + (MI_KEYSEG**) 0); DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg, (uchar*) key_buff,key_len);); nextflag=myisam_read_vec[search_flag]; diff --git a/myisam/mi_rkey.c b/myisam/mi_rkey.c index 86547d3ef04..60dec0449a0 100644 --- a/myisam/mi_rkey.c +++ b/myisam/mi_rkey.c @@ -23,10 +23,12 @@ /* Ordinary search_flag is 0 ; Give error if no record with key */ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len, - enum ha_rkey_function search_flag) + enum ha_rkey_function search_flag) { uchar *key_buff; MYISAM_SHARE *share=info->s; + MI_KEYDEF *keyinfo; + MI_KEYSEG *last_used_keyseg; uint pack_key_length, use_key_length, nextflag; DBUG_ENTER("mi_rkey"); DBUG_PRINT("enter",("base: %lx inx: %d search_flag: %d", @@ -36,23 +38,27 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len, DBUG_RETURN(my_errno); info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); + keyinfo= share->keyinfo + inx; if (!info->use_packed_key) { if (key_len == 0) key_len=USE_WHOLE_KEY; key_buff=info->lastkey+info->s->base.max_key_length; - pack_key_length=_mi_pack_key(info,(uint) inx,key_buff,(uchar*) key,key_len); - info->last_rkey_length=pack_key_length; - DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,share->keyinfo[inx].seg, - key_buff,pack_key_length);); + pack_key_length=_mi_pack_key(info, (uint) inx, key_buff, (uchar*) key, + key_len, &last_used_keyseg); + DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE, keyinfo->seg, + key_buff, pack_key_length);); } else { - /* key is already packed! */ + /* + key is already packed!; This happens when we are using a MERGE TABLE + */ key_buff=info->lastkey+info->s->base.max_key_length; - info->last_rkey_length=pack_key_length=key_len; + pack_key_length= key_len; bmove(key_buff,key,key_len); + last_used_keyseg= 0; } if (fast_mi_readinfo(info)) @@ -65,8 +71,8 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len, if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST))) use_key_length=USE_WHOLE_KEY; - if (!_mi_search(info,info->s->keyinfo+inx,key_buff,use_key_length, - myisam_read_vec[search_flag],info->s->state.key_root[inx])) + if (!_mi_search(info,keyinfo, key_buff, use_key_length, + myisam_read_vec[search_flag], info->s->state.key_root[inx])) { while (info->lastpos >= info->state->data_file_length) { @@ -76,7 +82,7 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len, exact key, because the keys are sorted according to position */ - if (_mi_search_next(info,info->s->keyinfo+inx,info->lastkey, + if (_mi_search_next(info, keyinfo, info->lastkey, info->lastkey_length, myisam_readnext_vec[search_flag], info->s->state.key_root[inx])) @@ -86,6 +92,12 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len, if (share->concurrent_insert) rw_unlock(&share->key_root_lock[inx]); + /* Calculate length of the found key; Used by mi_rnext_same */ + if ((keyinfo->flag & HA_VAR_LENGTH_KEY) && last_used_keyseg) + info->last_rkey_length= _mi_keylength_part(keyinfo, info->lastkey, + last_used_keyseg); + else + info->last_rkey_length= pack_key_length; if (!buf) DBUG_RETURN(info->lastpos==HA_OFFSET_ERROR ? my_errno : 0); @@ -99,6 +111,7 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len, /* Store key for read next */ memcpy(info->lastkey,key_buff,pack_key_length); + info->last_rkey_length= pack_key_length; bzero((char*) info->lastkey+pack_key_length,info->s->base.rec_reflength); info->lastkey_length=pack_key_length+info->s->base.rec_reflength; diff --git a/myisam/mi_search.c b/myisam/mi_search.c index 41d53e76241..32db69144d8 100644 --- a/myisam/mi_search.c +++ b/myisam/mi_search.c @@ -1441,6 +1441,37 @@ uint _mi_keylength(MI_KEYDEF *keyinfo, register uchar *key) } /* _mi_keylength */ +/* + Calculate length of part key. + + Used in mi_rkey() to find the key found for the key-part that was used. + This is needed in case of multi-byte character sets where we may search + after '0xDF' but find 'ss' +*/ + +uint _mi_keylength_part(MI_KEYDEF *keyinfo, register uchar *key, + MI_KEYSEG *end) +{ + reg1 MI_KEYSEG *keyseg; + uchar *start= key; + + for (keyseg=keyinfo->seg ; keyseg != end ; keyseg++) + { + if (keyseg->flag & HA_NULL_PART) + if (!*key++) + continue; + if (keyseg->flag & (HA_SPACE_PACK | HA_BLOB_PART | HA_VAR_LENGTH)) + { + uint length; + get_key_length(length,key); + key+=length; + } + else + key+= keyseg->length; + } + return (uint) (key-start); +} + /* Move a key */ uchar *_mi_move_key(MI_KEYDEF *keyinfo, uchar *to, uchar *from) diff --git a/myisam/mi_test2.c b/myisam/mi_test2.c index 93538e3ead7..e3a2ecfbb1f 100644 --- a/myisam/mi_test2.c +++ b/myisam/mi_test2.c @@ -639,14 +639,14 @@ int main(int argc, char *argv[]) if ((long) range_records < (long) records*7/10-2 || (long) range_records > (long) records*14/10+2) { - printf("mi_records_range for key: %d returned %ld; Should be about %ld\n", - i, range_records, records); + printf("mi_records_range for key: %d returned %lu; Should be about %lu\n", + i, (ulong) range_records, (ulong) records); goto end; } if (verbose && records) { - printf("mi_records_range returned %ld; Exact is %ld (diff: %4.2g %%)\n", - range_records,records, + printf("mi_records_range returned %lu; Exact is %lu (diff: %4.2g %%)\n", + (ulong) range_records, (ulong) records, labs((long) range_records-(long) records)*100.0/records); } @@ -660,8 +660,8 @@ int main(int argc, char *argv[]) || info.keys != keys) { puts("Wrong info from mi_info"); - printf("Got: records: %ld delete: %ld i_keys: %d\n", - info.records,info.deleted,info.keys); + printf("Got: records: %lu delete: %lu i_keys: %d\n", + (ulong) info.records, (ulong) info.deleted, info.keys); } if (verbose) { diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index 7c035bc6097..7631b245b9b 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -505,6 +505,8 @@ extern uchar *_mi_get_last_key(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *keypos, extern uchar *_mi_get_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key, uchar *keypos, uint *return_key_length); extern uint _mi_keylength(MI_KEYDEF *keyinfo,uchar *key); +extern uint _mi_keylength_part(MI_KEYDEF *keyinfo, register uchar *key, + MI_KEYSEG *end); extern uchar *_mi_move_key(MI_KEYDEF *keyinfo,uchar *to,uchar *from); extern int _mi_search_next(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key, uint key_length,uint nextflag,my_off_t pos); @@ -519,7 +521,7 @@ extern my_off_t _mi_new(MI_INFO *info,MI_KEYDEF *keyinfo); extern uint _mi_make_key(MI_INFO *info,uint keynr,uchar *key, const byte *record,my_off_t filepos); extern uint _mi_pack_key(MI_INFO *info,uint keynr,uchar *key,uchar *old, - uint key_length); + uint key_length, MI_KEYSEG **last_used_keyseg); extern int _mi_read_key_record(MI_INFO *info,my_off_t filepos,byte *buf); extern int _mi_read_cache(IO_CACHE *info,byte *buff,my_off_t pos, uint length,int re_read_if_possibly); diff --git a/myisam/sort.c b/myisam/sort.c index ddf565d5092..95ede6ddaa1 100644 --- a/myisam/sort.c +++ b/myisam/sort.c @@ -163,8 +163,8 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, if (maxbuffer == 0) { if (!no_messages) - printf(" - Dumping %lu keys\n",records); - if (write_index(info,sort_keys,(uint) records)) + printf(" - Dumping %lu keys\n", (ulong) records); + if (write_index(info,sort_keys, (uint) records)) goto err; /* purecov: inspected */ } else @@ -173,7 +173,7 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, if (maxbuffer >= MERGEBUFF2) { if (!no_messages) - printf(" - Merging %lu keys\n",records); /* purecov: tested */ + printf(" - Merging %lu keys\n", (ulong) records); /* purecov: tested */ if (merge_many_buff(info,keys,sort_keys, dynamic_element(&buffpek,0,BUFFPEK *),&maxbuffer,&tempfile)) goto err; /* purecov: inspected */ @@ -286,6 +286,8 @@ pthread_handler_decl(thr_find_all_keys,arg) uint idx, maxbuffer; uchar **sort_keys=0; + LINT_INIT(keys); + error=1; if (my_thread_init()) diff --git a/myisammrg/myrg_extra.c b/myisammrg/myrg_extra.c index d375b45df99..62cf5f01aba 100644 --- a/myisammrg/myrg_extra.c +++ b/myisammrg/myrg_extra.c @@ -33,7 +33,7 @@ int myrg_extra(MYRG_INFO *info,enum ha_extra_function function, if (function == HA_EXTRA_CACHE) { info->cache_in_use=1; - info->cache_size= (extra_arg ? *(long*) extra_arg : + info->cache_size= (extra_arg ? *(ulong*) extra_arg : my_default_record_cache_size); } else diff --git a/mysql-test/r/ctype_latin1_de.result b/mysql-test/r/ctype_latin1_de.result index b79bc67138c..630fef9b679 100644 --- a/mysql-test/r/ctype_latin1_de.result +++ b/mysql-test/r/ctype_latin1_de.result @@ -212,3 +212,55 @@ select * from t1 where match a against ("te*" in boolean mode)+0; a test drop table t1; +create table t1 (word varchar(255) not null, word2 varchar(255) not null, index(word)); +insert into t1 (word) values ('ss'),(0xDF),(0xE4),('ae'); +update t1 set word2=word; +select word, word=0xdf as t from t1 having t > 0; +word t +ß 1 +select word, word=cast(0xdf AS CHAR) as t from t1 having t > 0; +word t +ss 1 +ß 1 +select * from t1 where word=0xDF; +word word2 +ß ß +select * from t1 where word=CAST(0xDF as CHAR); +word word2 +ss ss +ß ß +select * from t1 where word2=0xDF; +word word2 +ß ß +select * from t1 where word2=CAST(0xDF as CHAR); +word word2 +ss ss +ß ß +select * from t1 where word='ae'; +word word2 +ä ä +ae ae +select * from t1 where word= 0xe4 or word=CAST(0xe4 as CHAR); +word word2 +ä ä +ae ae +select * from t1 where word between 0xDF and 0xDF; +word word2 +ß ß +select * from t1 where word between CAST(0xDF AS CHAR) and CAST(0xDF AS CHAR); +word word2 +ss ss +ß ß +select * from t1 where word like 'ae'; +word word2 +ae ae +select * from t1 where word like 'AE'; +word word2 +ae ae +select * from t1 where word like 0xDF; +word word2 +ß ß +select * from t1 where word like CAST(0xDF as CHAR); +word word2 +ß ß +drop table t1; diff --git a/mysql-test/r/ctype_ujis.result b/mysql-test/r/ctype_ujis.result new file mode 100644 index 00000000000..223a18f19e9 --- /dev/null +++ b/mysql-test/r/ctype_ujis.result @@ -0,0 +1,8 @@ +drop table if exists t1; +create table t1 (c text); +insert into t1 values (0xa4a2),(0xa4a3); +select hex(left(c,1)) from t1 group by c; +hex(left(c,1)) +A4A2 +A4A3 +drop table t1; diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 39214348244..c98f85f93d2 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1244,12 +1244,6 @@ insert into t1 (a) select b from t2; select count(*) from t1; count(*) 29267 -explain select a from t1 where a between 1 and 10000; -table type possible_keys key key_len ref rows Extra -t1 range PRIMARY PRIMARY 4 NULL 14745 Using where; Using index -explain select * from t1 where a between 1 and 10000; -table type possible_keys key key_len ref rows Extra -t1 range PRIMARY PRIMARY 4 NULL 14745 Using where explain select * from t1 where c between 1 and 10000; table type possible_keys key key_len ref rows Extra t1 range c c 5 NULL 1 Using where diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result index 9f6a8762325..e063b5c3e02 100644 --- a/mysql-test/r/join.result +++ b/mysql-test/r/join.result @@ -274,3 +274,101 @@ SELECT emp.rate_code, lr.base_rate FROM t1 AS emp LEFT JOIN t2 AS lr USING (site rate_code base_rate cust 20 drop table t1,t2; +CREATE TABLE t1 (ID INTEGER NOT NULL PRIMARY KEY, Value1 VARCHAR(255)); +CREATE TABLE t2 (ID INTEGER NOT NULL PRIMARY KEY, Value2 VARCHAR(255)); +INSERT INTO t1 VALUES (1, 'A'); +INSERT INTO t2 VALUES (1, 'B'); +SELECT * FROM t1 NATURAL JOIN t2 WHERE 1 AND (Value1 = 'A' AND Value2 <> 'B'); +ID Value1 ID Value2 +SELECT * FROM t1 NATURAL JOIN t2 WHERE 1 AND Value1 = 'A' AND Value2 <> 'B'; +ID Value1 ID Value2 +SELECT * FROM t1 NATURAL JOIN t2 WHERE (Value1 = 'A' AND Value2 <> 'B') AND 1; +ID Value1 ID Value2 +drop table t1,t2; +create table t1 (i int); +create table t2 (i int); +create table t3 (i int); +insert into t1 values(1),(2); +insert into t2 values(2),(3); +insert into t3 values (2),(4); +select * from t1 natural left join t2; +i i +1 NULL +2 2 +select * from t1 left join t2 on (t1.i=t2.i); +i i +1 NULL +2 2 +select * from t1 natural left join t2 natural left join t3; +i i i +1 NULL NULL +2 2 2 +select * from t1 left join t2 on (t1.i=t2.i) left join t3 on (t2.i=t3.i); +i i i +1 NULL NULL +2 2 2 +select * from t3 natural right join t2; +i i +2 2 +NULL 3 +select * from t3 right join t2 on (t3.i=t2.i); +i i +2 2 +NULL 3 +select * from t3 natural right join t2 natural right join t1; +i i i +NULL NULL 1 +2 2 2 +select * from t3 right join t2 on (t3.i=t2.i) right join t1 on (t2.i=t1.i); +i i i +NULL NULL 1 +2 2 2 +select * from t1,t2 natural left join t3 order by t1.i,t2.i,t3.i; +i i i +1 2 2 +1 3 NULL +2 2 2 +2 3 NULL +select * from t1,t2 left join t3 on (t2.i=t3.i) order by t1.i,t2.i,t3.i; +i i i +1 2 2 +1 3 NULL +2 2 2 +2 3 NULL +select t1.i,t2.i,t3.i from t2 natural left join t3,t1 order by t1.i,t2.i,t3.i; +i i i +1 2 2 +1 3 NULL +2 2 2 +2 3 NULL +select t1.i,t2.i,t3.i from t2 left join t3 on (t2.i=t3.i),t1 order by t1.i,t2.i,t3.i; +i i i +1 2 2 +1 3 NULL +2 2 2 +2 3 NULL +select * from t1,t2 natural right join t3 order by t1.i,t2.i,t3.i; +i i i +1 NULL 4 +1 2 2 +2 NULL 4 +2 2 2 +select * from t1,t2 right join t3 on (t2.i=t3.i) order by t1.i,t2.i,t3.i; +i i i +1 NULL 4 +1 2 2 +2 NULL 4 +2 2 2 +select t1.i,t2.i,t3.i from t2 natural right join t3,t1 order by t1.i,t2.i,t3.i; +i i i +1 NULL 4 +1 2 2 +2 NULL 4 +2 2 2 +select t1.i,t2.i,t3.i from t2 right join t3 on (t2.i=t3.i),t1 order by t1.i,t2.i,t3.i; +i i i +1 NULL 4 +1 2 2 +2 NULL 4 +2 2 2 +drop table t1,t2,t3; diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index fe30458d8de..81266f6562e 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -351,12 +351,7 @@ select t1.name, t2.name, t2.id,t3.id from t1 right join t2 on (t1.id = t2.owner) name name id id Antonio Paz El Gato 1 1 Antonio Paz Perrito 2 1 -NULL Happy 3 1 -NULL El Gato 1 2 -NULL Perrito 2 2 -NULL Happy 3 2 -NULL El Gato 1 3 -NULL Perrito 2 3 +NULL NULL NULL 2 Thimble Smith Happy 3 3 select t1.name, t2.name, t2.id, t2.owner, t3.id from t1 left join t2 on (t1.id = t2.owner) right join t1 as t3 on t3.id=t2.owner; name name id owner id diff --git a/mysql-test/r/repair.result b/mysql-test/r/repair.result index 8b50f9a92e8..adc09ded0e2 100644 --- a/mysql-test/r/repair.result +++ b/mysql-test/r/repair.result @@ -4,4 +4,8 @@ repair table t1 use_frm; Table Op Msg_type Msg_text test.t1 repair warning Number of rows changed from 0 to 1 test.t1 repair status OK -drop table if exists t1; +alter table t1 TYPE=HEAP; +repair table t1 use_frm; +Table Op Msg_type Msg_text +test.t1 repair error The handler for the table doesn't support repair +drop table t1; diff --git a/mysql-test/r/rpl_alter.result b/mysql-test/r/rpl_alter.result index 1dc73c6524a..729c7df6808 100644 --- a/mysql-test/r/rpl_alter.result +++ b/mysql-test/r/rpl_alter.result @@ -4,18 +4,18 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; slave start; -drop database if exists d1; -create database d1; -create table d1.t1 ( n int); -alter table d1.t1 add m int; -insert into d1.t1 values (1,2); -create table d1.t2 (n int); -insert into d1.t2 values (45); -rename table d1.t2 to d1.t3, d1.t1 to d1.t2; -select * from d1.t2; +drop database if exists test_$1; +create database test_$1; +create table test_$1.t1 ( n int); +alter table test_$1.t1 add m int; +insert into test_$1.t1 values (1,2); +create table test_$1.t2 (n int); +insert into test_$1.t2 values (45); +rename table test_$1.t2 to test_$1.t3, test_$1.t1 to test_$1.t2; +select * from test_$1.t2; n m 1 2 -select * from d1.t3; +select * from test_$1.t3; n 45 -drop database d1; +drop database test_$1; diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 1ad3043b4b2..a4c2533ec1a 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -3402,13 +3402,7 @@ a a a select * from t1 natural left join (t1 as t2 left join t1 as t3 using (a)); a a a 1 1 1 -2 1 NULL -3 1 NULL -1 2 NULL 2 2 2 -3 2 NULL -1 3 NULL -2 3 NULL 3 3 3 select * from (t1 as t2 left join t1 as t3 using (a)) right join t1 on t1.a>1; a a a @@ -3464,13 +3458,7 @@ a a a select * from t1 natural join (t1 as t2 left join t1 as t3 using (a)); a a a 1 1 1 -2 1 NULL -3 1 NULL -1 2 NULL 2 2 2 -3 2 NULL -1 3 NULL -2 3 NULL 3 3 3 select * from (t1 as t2 left join t1 as t3 using (a)) natural join t1; a a a diff --git a/mysql-test/t/ctype_latin1_de-master.opt b/mysql-test/t/ctype_latin1_de-master.opt index 98accd58c46..895a62364d6 100644 --- a/mysql-test/t/ctype_latin1_de-master.opt +++ b/mysql-test/t/ctype_latin1_de-master.opt @@ -1 +1,2 @@ ---default-character-set=latin1_de +--default-character-set=latin1_de --new + diff --git a/mysql-test/t/ctype_latin1_de.test b/mysql-test/t/ctype_latin1_de.test index 4b96f5f5867..6353650f420 100644 --- a/mysql-test/t/ctype_latin1_de.test +++ b/mysql-test/t/ctype_latin1_de.test @@ -45,3 +45,26 @@ select * from t1 where a like "test%"; select * from t1 where a like "te_t"; select * from t1 where match a against ("te*" in boolean mode)+0; drop table t1; + +# +# Test bug report #152 (problem with index on latin1_de) +# + +create table t1 (word varchar(255) not null, word2 varchar(255) not null, index(word)); +insert into t1 (word) values ('ss'),(0xDF),(0xE4),('ae'); +update t1 set word2=word; +select word, word=0xdf as t from t1 having t > 0; +select word, word=cast(0xdf AS CHAR) as t from t1 having t > 0; +select * from t1 where word=0xDF; +select * from t1 where word=CAST(0xDF as CHAR); +select * from t1 where word2=0xDF; +select * from t1 where word2=CAST(0xDF as CHAR); +select * from t1 where word='ae'; +select * from t1 where word= 0xe4 or word=CAST(0xe4 as CHAR); +select * from t1 where word between 0xDF and 0xDF; +select * from t1 where word between CAST(0xDF AS CHAR) and CAST(0xDF AS CHAR); +select * from t1 where word like 'ae'; +select * from t1 where word like 'AE'; +select * from t1 where word like 0xDF; +select * from t1 where word like CAST(0xDF as CHAR); +drop table t1; diff --git a/mysql-test/t/ctype_ujis-master.opt b/mysql-test/t/ctype_ujis-master.opt new file mode 100644 index 00000000000..1f4183d5027 --- /dev/null +++ b/mysql-test/t/ctype_ujis-master.opt @@ -0,0 +1 @@ +--default-character-set=ujis diff --git a/mysql-test/t/ctype_ujis.test b/mysql-test/t/ctype_ujis.test new file mode 100644 index 00000000000..cd1dc965000 --- /dev/null +++ b/mysql-test/t/ctype_ujis.test @@ -0,0 +1,13 @@ +# +# Tests with the ujis character set +# +drop table if exists t1; + +# +# Test problem with LEFT() +# + +create table t1 (c text); +insert into t1 values (0xa4a2),(0xa4a3); +select hex(left(c,1)) from t1 group by c; +drop table t1; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index 4fb9351020e..d65b9b1638e 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -837,8 +837,6 @@ insert into t1 (a) select b from t2; insert into t2 (a) select b from t1; insert into t1 (a) select b from t2; select count(*) from t1; -explain select a from t1 where a between 1 and 10000; -explain select * from t1 where a between 1 and 10000; explain select * from t1 where c between 1 and 10000; update t1 set c=a; explain select * from t1 where c between 1 and 10000; diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test index 63ec90f854c..08cc5731723 100644 --- a/mysql-test/t/join.test +++ b/mysql-test/t/join.test @@ -271,3 +271,49 @@ INSERT INTO t2 VALUES ('rivercats','cust',20); SELECT emp.rate_code, lr.base_rate FROM t1 AS emp LEFT JOIN t2 AS lr USING (siteid, rate_code) WHERE emp.emp_id = 'psmith' AND lr.siteid = 'rivercats'; SELECT emp.rate_code, lr.base_rate FROM t1 AS emp LEFT JOIN t2 AS lr USING (siteid, rate_code) WHERE lr.siteid = 'rivercats' AND emp.emp_id = 'psmith'; drop table t1,t2; + +# +# Problem with internal list handling when reducing WHERE +# + +CREATE TABLE t1 (ID INTEGER NOT NULL PRIMARY KEY, Value1 VARCHAR(255)); +CREATE TABLE t2 (ID INTEGER NOT NULL PRIMARY KEY, Value2 VARCHAR(255)); +INSERT INTO t1 VALUES (1, 'A'); +INSERT INTO t2 VALUES (1, 'B'); + +SELECT * FROM t1 NATURAL JOIN t2 WHERE 1 AND (Value1 = 'A' AND Value2 <> 'B'); +SELECT * FROM t1 NATURAL JOIN t2 WHERE 1 AND Value1 = 'A' AND Value2 <> 'B'; +SELECT * FROM t1 NATURAL JOIN t2 WHERE (Value1 = 'A' AND Value2 <> 'B') AND 1; +drop table t1,t2; + +# +# Test combination of join methods +# + +create table t1 (i int); +create table t2 (i int); +create table t3 (i int); +insert into t1 values(1),(2); +insert into t2 values(2),(3); +insert into t3 values (2),(4); + +select * from t1 natural left join t2; +select * from t1 left join t2 on (t1.i=t2.i); +select * from t1 natural left join t2 natural left join t3; +select * from t1 left join t2 on (t1.i=t2.i) left join t3 on (t2.i=t3.i); + +select * from t3 natural right join t2; +select * from t3 right join t2 on (t3.i=t2.i); +select * from t3 natural right join t2 natural right join t1; +select * from t3 right join t2 on (t3.i=t2.i) right join t1 on (t2.i=t1.i); + +select * from t1,t2 natural left join t3 order by t1.i,t2.i,t3.i; +select * from t1,t2 left join t3 on (t2.i=t3.i) order by t1.i,t2.i,t3.i; +select t1.i,t2.i,t3.i from t2 natural left join t3,t1 order by t1.i,t2.i,t3.i; +select t1.i,t2.i,t3.i from t2 left join t3 on (t2.i=t3.i),t1 order by t1.i,t2.i,t3.i; + +select * from t1,t2 natural right join t3 order by t1.i,t2.i,t3.i; +select * from t1,t2 right join t3 on (t2.i=t3.i) order by t1.i,t2.i,t3.i; +select t1.i,t2.i,t3.i from t2 natural right join t3,t1 order by t1.i,t2.i,t3.i; +select t1.i,t2.i,t3.i from t2 right join t3 on (t2.i=t3.i),t1 order by t1.i,t2.i,t3.i; +drop table t1,t2,t3; diff --git a/mysql-test/t/repair.test b/mysql-test/t/repair.test index 6d79014b23d..b901fb3467f 100644 --- a/mysql-test/t/repair.test +++ b/mysql-test/t/repair.test @@ -5,4 +5,6 @@ drop table if exists t1; create table t1 SELECT 1,"table 1"; repair table t1 use_frm; -drop table if exists t1; +alter table t1 TYPE=HEAP; +repair table t1 use_frm; +drop table t1; diff --git a/mysql-test/t/rpl_alter.test b/mysql-test/t/rpl_alter.test index 710dd2d09d6..f1fbf60776b 100644 --- a/mysql-test/t/rpl_alter.test +++ b/mysql-test/t/rpl_alter.test @@ -1,19 +1,19 @@ source include/master-slave.inc; -drop database if exists d1; -create database d1; -create table d1.t1 ( n int); -alter table d1.t1 add m int; -insert into d1.t1 values (1,2); -create table d1.t2 (n int); -insert into d1.t2 values (45); -rename table d1.t2 to d1.t3, d1.t1 to d1.t2; +drop database if exists test_$1; +create database test_$1; +create table test_$1.t1 ( n int); +alter table test_$1.t1 add m int; +insert into test_$1.t1 values (1,2); +create table test_$1.t2 (n int); +insert into test_$1.t2 values (45); +rename table test_$1.t2 to test_$1.t3, test_$1.t1 to test_$1.t2; save_master_pos; connection slave; sync_with_master; -select * from d1.t2; -select * from d1.t3; +select * from test_$1.t2; +select * from test_$1.t3; connection master; -drop database d1; +drop database test_$1; save_master_pos; connection slave; sync_with_master; diff --git a/mysys/charset.c b/mysys/charset.c index 235fcb08023..0a76cf86a54 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -77,7 +77,7 @@ static my_bool get_word(struct simpleconfig_buf_st *fb, char *buf) endptr = fb->buf; } - while (!isspace(*endptr)) + while (*endptr && !isspace(*endptr)) *buf++= *endptr++; *buf=0; fb->p = endptr; diff --git a/mysys/default.c b/mysys/default.c index 26121cc0e56..c47d2719ab5 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -249,8 +249,13 @@ static my_bool search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc, MY_STAT stat_info; if (!my_stat(name,&stat_info,MYF(0))) return 0; - /* ignore world-writeable _regular_ files */ - if (stat_info.st_mode & S_IWOTH && stat_info.st_mode & S_IFREG) + /* + Ignore world-writable regular files. + This is mainly done to protect us to not read a file created by + the mysqld server, but the check is still valid in most context. + */ + if ((stat_info.st_mode & S_IWOTH) && + (stat_info.st_mode & S_IFMT) == S_IFREG) { fprintf(stderr, "warning: World-writeable config file %s is ignored\n", name); diff --git a/mysys/mf_path.c b/mysys/mf_path.c index 23eadd2acce..1ecd5fbb2b1 100644 --- a/mysys/mf_path.c +++ b/mysys/mf_path.c @@ -77,6 +77,9 @@ my_string my_path(my_string to, const char *progname, #define F_OK 0 #define PATH_SEP ';' #define PROGRAM_EXTENSION ".exe" +#elif defined(__NETWARE__) +#define PATH_SEP ';' +#define PROGRAM_EXTENSION ".nlm" #else #define PATH_SEP ':' #endif diff --git a/mysys/my_pthread.c b/mysys/my_pthread.c index 1eb15d92bc9..4f472f61593 100644 --- a/mysys/my_pthread.c +++ b/mysys/my_pthread.c @@ -90,6 +90,29 @@ void *my_pthread_getspecific_imp(pthread_key_t key) } #endif +#ifdef __NETWARE__ +/* +don't kill the LibC Reaper thread or the main thread +*/ +#include <nks/thread.h> +#undef pthread_exit +void my_pthread_exit(void *status) +{ + NXThreadId_t tid = NXThreadGetId(); + NXContext_t ctx; + char name[PATH_MAX] = ""; + + NXThreadGetContext(tid, &ctx); + NXContextGetName(ctx, name, PATH_MAX); + + // "MYSQLD.NLM's LibC Reaper" or "MYSQLD.NLM's main thread" + // with a debug build of LibC the reaper can have different names + if (!strindex(name, "\'s")) + { + pthread_exit(status); + } +} +#endif /* Some functions for RTS threads, AIX, Siemens Unix and UnixWare 7 (and DEC OSF/1 3.2 too) */ diff --git a/sql-bench/Makefile.am b/sql-bench/Makefile.am index ab6be7269e3..579a2a9f7fe 100644 --- a/sql-bench/Makefile.am +++ b/sql-bench/Makefile.am @@ -41,12 +41,9 @@ EXTRA_DIST = $(EXTRA_SCRIPTS) dist-hook: mkdir -p $(distdir)/Data/ATIS $(distdir)/Data/Wisconsin \ - $(distdir)/Results $(distdir)/Results-win32 \ $(distdir)/limits $(distdir)/Comments for i in $(srcdir)/Data/ATIS/*.* ; do $(INSTALL_DATA) $$i $(distdir)/Data/ATIS ; done for i in $(srcdir)/Data/Wisconsin/*.* ; do $(INSTALL_DATA) $$i $(distdir)/Data/Wisconsin ; done - for i in $(srcdir)/Results/*-* ; do $(INSTALL_DATA) $$i $(distdir)/Results; done - for i in $(srcdir)/Results-win32/*-* ; do $(INSTALL_DATA) $$i $(distdir)/Results-win32; done for i in $(srcdir)/limits/*.* ; do $(INSTALL_DATA) $$i $(distdir)/limits; done for i in $(srcdir)/Comments/*.* ; do $(INSTALL_DATA) $$i $(distdir)/Comments; done @@ -55,15 +52,11 @@ install-data-local: $(DESTDIR)$(benchdir)/Data \ $(DESTDIR)$(benchdir)/Data/ATIS \ $(DESTDIR)$(benchdir)/Data/Wisconsin \ - $(DESTDIR)$(benchdir)/Results \ - $(DESTDIR)$(benchdir)/Results-win32 \ $(DESTDIR)$(benchdir)/limits \ $(DESTDIR)$(benchdir)/Comments $(INSTALL_DATA) $(srcdir)/README $(DESTDIR)$(benchdir) for i in $(srcdir)/Data/ATIS/*.* ; do $(INSTALL_DATA) $$i $(DESTDIR)$(benchdir)/Data/ATIS ; done for i in $(srcdir)/Data/Wisconsin/*.* ; do $(INSTALL_DATA) $$i $(DESTDIR)$(benchdir)/Data/Wisconsin ; done - for i in $(srcdir)/Results/*-* ; do $(INSTALL_DATA) $$i $(DESTDIR)$(benchdir)/Results; done - for i in $(srcdir)/Results-win32/*-* ; do $(INSTALL_DATA) $$i $(DESTDIR)$(benchdir)/Results-win32; done for i in $(srcdir)/limits/*.* ; do $(INSTALL_DATA) $$i $(DESTDIR)$(benchdir)/limits; done for i in $(srcdir)/Comments/*.* ; do $(INSTALL_DATA) $$i $(DESTDIR)$(benchdir)/Comments; done diff --git a/sql/field.cc b/sql/field.cc index eb7d3dc5686..a2663626723 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -162,6 +162,14 @@ static bool test_if_real(const char *str,int length) } +static inline uint field_length_without_space(const char *ptr, uint length) +{ + const char *end= ptr+length; + while (end > ptr && end[-1] == ' ') + end--; + return (uint) (end-ptr); +} + /**************************************************************************** ** Functions for the base classes ** This is an unpacked number. @@ -3673,8 +3681,21 @@ int Field_string::cmp(const char *a_ptr, const char *b_ptr) { if (binary_flag) return memcmp(a_ptr,b_ptr,field_length); - else - return my_sortcmp(a_ptr,b_ptr,field_length); +#ifdef USE_STRCOLL + if (use_strcoll(default_charset_info)) + { + /* + We have to remove end space to be able to compare multi-byte-characters + like in latin_de 'ae' and 0xe4 + */ + uint a_length= field_length_without_space(a_ptr, field_length); + uint b_length= field_length_without_space(b_ptr, field_length); + return my_strnncoll(default_charset_info, + (const uchar*) a_ptr, a_length, + (const uchar*) b_ptr, b_length); + } +#endif + return my_sortcmp(a_ptr,b_ptr,field_length); } void Field_string::sort_string(char *to,uint length) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 1363227605e..73654536083 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -100,7 +100,7 @@ char* innobase_unix_file_flush_method = NULL; /* Below we have boolean-valued start-up parameters, and their default values */ -uint innobase_flush_log_at_trx_commit = 0; +uint innobase_flush_log_at_trx_commit = 1; my_bool innobase_log_archive = FALSE; my_bool innobase_use_native_aio = FALSE; my_bool innobase_fast_shutdown = TRUE; @@ -1911,13 +1911,6 @@ ha_innobase::write_row( build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW); } - if (user_thd->lex.sql_command == SQLCOM_INSERT - && user_thd->lex.duplicates == DUP_IGNORE) { - prebuilt->trx->ignore_duplicates_in_insert = TRUE; - } else { - prebuilt->trx->ignore_duplicates_in_insert = FALSE; - } - srv_conc_enter_innodb(prebuilt->trx); error = row_insert_for_mysql((byte*) record, prebuilt); @@ -1958,8 +1951,6 @@ ha_innobase::write_row( } } - prebuilt->trx->ignore_duplicates_in_insert = FALSE; - error = convert_error_code_to_mysql(error, user_thd); /* Tell InnoDB server that there might be work for diff --git a/sql/item.cc b/sql/item.cc index 4fefae7358f..79501755cbf 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -576,6 +576,14 @@ inline uint char_val(char X) X-'a'+10); } +/* In MySQL 4.1 this will always return STRING_RESULT */ + +enum Item_result Item_varbinary::result_type () const +{ + return (current_thd->variables.new_mode) ? STRING_RESULT : INT_RESULT; +} + + Item_varbinary::Item_varbinary(const char *str, uint str_length) { name=(char*) str-2; // Lex makes this start with 0x diff --git a/sql/item.h b/sql/item.h index 5e2c2ccc056..09d428509d0 100644 --- a/sql/item.h +++ b/sql/item.h @@ -353,7 +353,7 @@ public: String *val_str(String*) { return &str_value; } bool save_in_field(Field *field, bool no_conversions); void make_field(Send_field *field); - enum Item_result result_type () const { return INT_RESULT; } + enum Item_result result_type () const; unsigned int size_of() { return sizeof(*this);} }; diff --git a/sql/item_create.cc b/sql/item_create.cc index 7e082bc174c..6809d6892b0 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -297,7 +297,7 @@ Item *create_func_current_user() char buff[HOSTNAME_LENGTH+USERNAME_LENGTH+2]; uint length; - length= (uint) (strxmov(buff, thd->priv_user, "@", thd->host_or_ip, NullS) - + length= (uint) (strxmov(buff, thd->priv_user, "@", thd->priv_host, NullS) - buff); return new Item_string(NullS, thd->memdup(buff, length), length); } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 2496e1acabe..9876b77e8cb 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -27,9 +27,6 @@ #include "mysql_priv.h" #include "sql_acl.h" #include <m_ctype.h> -#ifdef HAVE_CRYPT_H -#include <crypt.h> -#endif #ifdef HAVE_OPENSSL #include <openssl/des.h> #endif /* HAVE_OPENSSL */ @@ -899,7 +896,7 @@ void Item_str_func::left_right_max_length() max_length=args[0]->max_length; if (args[1]->const_item()) { - int length=(int) args[1]->val_int(); + int length=(int) args[1]->val_int()*default_charset_info->mbmaxlen; if (length <= 0) max_length=0; else @@ -992,7 +989,7 @@ void Item_func_substr::fix_length_and_dec() } if (arg_count == 3 && args[2]->const_item()) { - int32 length= (int32) args[2]->val_int(); + int32 length= (int32) args[2]->val_int() * default_charset_info->mbmaxlen; if (length <= 0) max_length=0; /* purecov: inspected */ else diff --git a/sql/log_event.cc b/sql/log_event.cc index 05d5788f5ae..bbea89bfd3f 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -717,7 +717,7 @@ void Start_log_event::print(FILE* file, bool short_form, char* last_db) print_header(file); fprintf(file, "\tStart: binlog v %d, server v %s created ", binlog_version, server_version); - print_timestamp(file, (time_t*)&created); + print_timestamp(file, &created); fputc('\n', file); fflush(file); } diff --git a/sql/log_event.h b/sql/log_event.h index b46f78d2ce0..4b32894d787 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -452,14 +452,14 @@ extern char server_version[SERVER_VERSION_LENGTH]; class Start_log_event: public Log_event { public: - uint32 created; + time_t created; uint16 binlog_version; char server_version[ST_SERVER_VER_LEN]; #ifndef MYSQL_CLIENT Start_log_event() :Log_event(), binlog_version(BINLOG_VERSION) { - created = (uint32) when; + created = (time_t) when; memcpy(server_version, ::server_version, ST_SERVER_VER_LEN); } void pack_info(String* packet); diff --git a/sql/mini_client.cc b/sql/mini_client.cc index 38b3c22b91b..6489685c923 100644 --- a/sql/mini_client.cc +++ b/sql/mini_client.cc @@ -243,7 +243,7 @@ static void mc_free_old_query(MYSQL *mysql) static int mc_sock_connect(my_socket s, const struct sockaddr *name, uint namelen, uint to) { -#if defined(__WIN__) || defined(OS2) +#if defined(__WIN__) || defined(OS2) || defined(__NETWARE__) return connect(s, (struct sockaddr*) name, namelen); #else int flags, res, s_err; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3910bfc880b..33724c7100e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -204,12 +204,12 @@ static char **opt_argv; #ifdef __WIN__ #undef MYSQL_SERVER_SUFFIX #ifdef __NT__ -#if defined(HAVE_INNOBASE_DB) || defined(HAVE_BERKELEY_DB) +#if defined(HAVE_BERKELEY_DB) #define MYSQL_SERVER_SUFFIX "-max-nt" #else #define MYSQL_SERVER_SUFFIX "-nt" #endif /* ...DB */ -#elif defined(HAVE_INNOBASE_DB) || defined(HAVE_BERKELEY_DB) +#elif defined(HAVE_BERKELEY_DB) #define MYSQL_SERVER_SUFFIX "-max" #else #define MYSQL_SERVER_SUFFIX "" @@ -797,9 +797,9 @@ static void __cdecl kill_server(int sig_ptr) #ifdef __NETWARE__ pthread_join(select_thread, NULL); // wait for main thread -#else - pthread_exit(0); /* purecov: deadcode */ #endif /* __NETWARE__ */ + + pthread_exit(0); /* purecov: deadcode */ RETURN_FROM_KILL_SERVER; } @@ -856,13 +856,11 @@ void unireg_end(void) { clean_up(1); my_thread_end(); -#ifndef __NETWARE__ -#ifdef SIGNALS_DONT_BREAK_READ +#if defined(SIGNALS_DONT_BREAK_READ) && !defined(__NETWARE__) exit(0); #else pthread_exit(0); // Exit is in main thread #endif -#endif /* __NETWARE__ */ } @@ -1233,7 +1231,7 @@ void yyerror(const char *s) { NET *net=my_pthread_getspecific_ptr(NET*,THR_NET); char *yytext=(char*) current_lex->tok_start; - if (!strcmp(s,"parse error")) + if (!strcmp(s,"parse error") || !strcmp(s,"syntax error")) s=ER(ER_SYNTAX_ERROR); net_printf(net,ER_PARSE_ERROR, s, yytext ? (char*) yytext : "", current_lex->yylineno); @@ -1694,9 +1692,10 @@ extern "C" void *signal_hand(void *arg __attribute__((unused))) /* Setup alarm handler - The two extra handlers are for slave threads + This should actually be '+ max_number_of_slaves' instead of +10, + but the +10 should be quite safe. */ - init_thr_alarm(max_connections+max_insert_delayed_threads+2); + init_thr_alarm(max_connections+max_insert_delayed_threads+10); #if SIGINT != THR_KILL_SIGNAL (void) sigemptyset(&set); // Setup up SIGINT for debug (void) sigaddset(&set,SIGINT); // For debugging @@ -3787,7 +3786,7 @@ replicating a LOAD DATA INFILE command", (gptr*) &max_connect_errors, (gptr*) &max_connect_errors, 0, GET_ULONG, REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ~0L, 0, 1, 0}, {"max_delayed_threads", OPT_MAX_DELAYED_THREADS, - "Don't start more than this number of threads to handle INSERT DELAYED statements. This option does not yet have effect (on TODO), unless it is set to zero, which means INSERT DELAYED is not used.", + "Don't start more than this number of threads to handle INSERT DELAYED statements. If set to zero, which means INSERT DELAYED is not used.", (gptr*) &max_insert_delayed_threads, (gptr*) &max_insert_delayed_threads, 0, GET_ULONG, REQUIRED_ARG, 20, 0, 16384, 0, 1, 0}, {"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE, diff --git a/sql/slave.cc b/sql/slave.cc index 771317f9431..e6215356ad1 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2355,9 +2355,7 @@ err: goto slave_begin; #endif my_thread_end(); -#ifndef __NETWARE__ pthread_exit(0); -#endif /* __NETWARE__ */ DBUG_RETURN(0); // Can't return anything here } @@ -2500,9 +2498,7 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ goto slave_begin; #endif my_thread_end(); // clean-up before broadcasting termination -#ifndef __NETWARE__ pthread_exit(0); -#endif /* __NETWARE__ */ DBUG_RETURN(0); // Can't return anything here } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 28cb3eed4ef..c2afa2818e0 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -114,7 +114,7 @@ static ACL_USER *find_acl_user(const char *host, const char *user); static bool update_user_table(THD *thd, const char *host, const char *user, const char *new_password); static void update_hostname(acl_host_and_ip *host, const char *hostname); -static bool compare_hostname(const acl_host_and_ip *host, const char *hostname, +static bool compare_hostname(const acl_host_and_ip *host,const char *hostname, const char *ip); /* @@ -492,7 +492,8 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b) */ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, - const char *password,const char *message,char **priv_user, + const char *password,const char *message, + char **priv_user, char **priv_host, bool old_ver, USER_RESOURCES *mqh) { ulong user_access=NO_ACCESS; @@ -526,10 +527,10 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, #ifdef HAVE_OPENSSL Vio *vio=thd->net.vio; /* - In this point we know that user is allowed to connect - from given host by given username/password pair. Now - we check if SSL is required, if user is using SSL and - if X509 certificate attributes are OK + In this point we know that user is allowed to connect + from given host by given username/password pair. Now + we check if SSL is required, if user is using SSL and + if X509 certificate attributes are OK */ switch (acl_user->ssl_type) { case SSL_TYPE_NOT_SPECIFIED: // Impossible @@ -577,7 +578,7 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, X509* cert=SSL_get_peer_certificate(vio->ssl_); DBUG_PRINT("info",("checkpoint 2")); /* If X509 issuer is speified, we check it... */ - if (acl_user->x509_issuer) + if (acl_user->x509_issuer) { DBUG_PRINT("info",("checkpoint 3")); char *ptr = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); @@ -605,7 +606,7 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, if (strcmp(acl_user->x509_subject,ptr)) { if (global_system_variables.log_warnings) - sql_print_error("X509 subject mismatch: '%s' vs '%s'", + sql_print_error("X509 subject mismatch: '%s' vs '%s'", acl_user->x509_subject, ptr); user_access=NO_ACCESS; } @@ -622,6 +623,7 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, *mqh=acl_user->user_resource; if (!acl_user->user) *priv_user=(char*) ""; // Change to anonymous user /* purecov: inspected */ + *priv_host=acl_user->host.hostname; break; } #ifndef ALLOW_DOWNGRADE_OF_USERS @@ -1993,10 +1995,10 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, } -int mysql_table_grant (THD *thd, TABLE_LIST *table_list, - List <LEX_USER> &user_list, - List <LEX_COLUMN> &columns, ulong rights, - bool revoke_grant) +int mysql_table_grant(THD *thd, TABLE_LIST *table_list, + List <LEX_USER> &user_list, + List <LEX_COLUMN> &columns, ulong rights, + bool revoke_grant) { ulong column_priv = 0; List_iterator <LEX_USER> str_list (user_list); @@ -2370,7 +2372,7 @@ my_bool grant_init(THD *org_thd) mem_check->ok() && hash_insert(&hash_tables,(byte*) mem_check)) { /* This could only happen if we are out memory */ - grant_option = FALSE; /* purecov: deadcode */ + grant_option= FALSE; /* purecov: deadcode */ goto end_unlock; } } @@ -2400,7 +2402,8 @@ end: void grant_reload(THD *thd) { - HASH old_hash_tables;bool old_grant_option; + HASH old_hash_tables; + bool old_grant_option; MEM_ROOT old_mem; DBUG_ENTER("grant_reload"); @@ -2409,14 +2412,14 @@ void grant_reload(THD *thd) pthread_mutex_lock(&LOCK_grant); grant_version++; old_hash_tables=hash_tables; - old_grant_option = grant_option; + old_grant_option= grant_option; old_mem = memex; if (grant_init(thd)) { // Error. Revert to old hash grant_free(); /* purecov: deadcode */ hash_tables=old_hash_tables; /* purecov: deadcode */ - grant_option = old_grant_option; /* purecov: deadcode */ + grant_option= old_grant_option; /* purecov: deadcode */ memex = old_mem; /* purecov: deadcode */ } else diff --git a/sql/sql_acl.h b/sql/sql_acl.h index 6925b6b406c..26e445fb7ea 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -87,7 +87,8 @@ void acl_free(bool end=0); ulong acl_get(const char *host, const char *ip, const char *bin_ip, const char *user, const char *db); ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, - const char *password,const char *scramble,char **priv_user, + const char *password,const char *scramble, + char **priv_user, char **priv_host, bool old_ver, USER_RESOURCES *max); bool acl_check_host(const char *host, const char *ip); bool check_change_password(THD *thd, const char *host, const char *user); diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 5d3f9a0595c..d6abe6497df 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -284,7 +284,6 @@ void field_str::add() char buff[MAX_FIELD_WIDTH], *ptr; String s(buff, sizeof(buff)), *res; ulong length; - TREE_ELEMENT *element; if (!(res = item->val_str(&s))) { diff --git a/sql/sql_base.cc b/sql/sql_base.cc index d01dc50cf9d..0f0c3c97ed2 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1984,9 +1984,9 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, (!db_name || !strcmp(tables->db,db_name)))) { /* Ensure that we have access right to all columns */ - if (grant_option && !((thd->master_access | table->grant.privilege) & - table->grant.want_privilege) && - check_grant_all_columns(thd,SELECT_ACL,table) ) + if (grant_option && !(table->grant.privilege & + table->grant.want_privilege) && + check_grant_all_columns(thd,SELECT_ACL,table)) DBUG_RETURN(-1); Field **ptr=table->field,*field; thd->used_tables|=table->map; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index dc687e483e8..2a65291c273 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -110,6 +110,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), net.last_error[0]=0; // If error on boot ull=0; system_thread=cleanup_done=0; + peer_port= 0; // For SHOW PROCESSLIST transaction.changed_tables = 0; #ifdef __WIN__ real_id = 0; diff --git a/sql/sql_class.h b/sql/sql_class.h index ad0540de18c..26551b01da1 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -351,14 +351,14 @@ public: db - currently selected database ip - client IP */ - char *host,*user,*priv_user,*db,*ip; + char *host,*user,*priv_user,*priv_host,*db,*ip; /* remote (peer) port */ uint16 peer_port; /* Points to info-string that will show in SHOW PROCESSLIST */ const char *proc_info; /* points to host if host is available, otherwise points to ip */ const char *host_or_ip; - + uint client_capabilities; /* What the client supports */ /* Determines if which non-standard SQL behaviour should be enabled */ uint sql_mode; @@ -366,7 +366,6 @@ public: ulong master_access; /* Global privileges from mysql.user */ ulong db_access; /* Privileges for current db */ - /* open_tables - list of regular tables in use by this thread temporary_tables - list of temp tables in use by this thread diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 900c87d83a5..7e58b5d4582 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -362,11 +362,11 @@ bool mysql_change_db(THD *thd,const char *name) { net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR, thd->priv_user, - thd->host_or_ip, + thd->priv_host, dbname); mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR), thd->priv_user, - thd->host_or_ip, + thd->priv_host, dbname); my_free(dbname,MYF(0)); DBUG_RETURN(1); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 0e7a487276d..e02f457fd77 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -643,6 +643,9 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list) /* no match; create a new thread to handle the table */ if (!(tmp=find_handler(thd,table_list))) { + /* Don't create more than max_insert_delayed_threads */ + if (delayed_insert_threads >= max_insert_delayed_threads) + DBUG_RETURN(0); thd->proc_info="Creating delayed handler"; pthread_mutex_lock(&LOCK_delayed_create); if (!(tmp=find_handler(thd,table_list))) // Was just created @@ -1021,12 +1024,12 @@ extern "C" pthread_handler_decl(handle_delayed_insert,arg) while (!thd->killed) { int error; -#if (defined(HAVE_BROKEN_COND_TIMEDWAIT) || defined(HAVE_LINUXTHREADS)) +#if defined(HAVE_BROKEN_COND_TIMEDWAIT) error=pthread_cond_wait(&di->cond,&di->mutex); #else error=pthread_cond_timedwait(&di->cond,&di->mutex,&abstime); #ifdef EXTRA_DEBUG - if (error && error != EINTR) + if (error && error != EINTR && error != ETIMEDOUT) { fprintf(stderr, "Got error %d from pthread_cond_timedwait\n",error); DBUG_PRINT("error",("Got error %d from pthread_cond_timedwait", diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 62ed0fc5bed..ee573672c35 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -179,7 +179,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, else { unpack_filename(name,ex->file_name); -#if !defined(__WIN__) && !defined(OS2) +#if !defined(__WIN__) && !defined(OS2) && ! defined(__NETWARE__) MY_STAT stat_info; if (!my_stat(name,&stat_info,MYF(MY_WME))) DBUG_RETURN(-1); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 29bd1393322..cff7627460e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -186,7 +186,7 @@ end: /* Check if user is ok Updates: - thd->user, thd->master_access, thd->priv_user, thd->db, thd->db_access + thd->{user,master_access,priv_user,priv_host,db,db_access} */ static bool check_user(THD *thd,enum_server_command command, const char *user, @@ -205,14 +205,15 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, return 1; } thd->master_access=acl_getroot(thd, thd->host, thd->ip, thd->user, - passwd, thd->scramble, &thd->priv_user, + passwd, thd->scramble, + &thd->priv_user, &thd->priv_host, protocol_version == 9 || !(thd->client_capabilities & CLIENT_LONG_PASSWORD),&ur); DBUG_PRINT("info", - ("Capabilities: %d packet_length: %ld Host: '%s' User: '%s' Using password: %s Access: %u db: '%s'", + ("Capabilities: %d packet_length: %ld Host: '%s' Login user: '%s' Priv_user: '%s' Using password: %s Access: %u db: '%s'", thd->client_capabilities, thd->max_client_packet_length, - thd->host_or_ip, thd->priv_user, + thd->host_or_ip, thd->user, thd->priv_user, passwd[0] ? "yes": "no", thd->master_access, thd->db ? thd->db : "*none*")); if (thd->master_access & NO_ACCESS) @@ -517,7 +518,6 @@ check_connections(THD *thd) DBUG_PRINT("info",("Host: %s",thd->host)); thd->host_or_ip= thd->host; thd->ip= 0; - thd->peer_port= 0; bzero((char*) &thd->remote,sizeof(struct sockaddr)); } /* Ensure that wrong hostnames doesn't cause buffer overflows */ @@ -2520,12 +2520,20 @@ error: /**************************************************************************** Get the user (global) and database privileges for all used tables - Returns true (error) if we can't get the privileges and we don't use - table/column grants. - The idea of EXTRA_ACL is that one will be granted access to the table if - one has the asked privilege on any column combination of the table; For - example to be able to check a table one needs to have SELECT privilege on - any column of the table. + + NOTES + The idea of EXTRA_ACL is that one will be granted access to the table if + one has the asked privilege on any column combination of the table; For + example to be able to check a table one needs to have SELECT privilege on + any column of the table. + + RETURN + 0 ok + 1 If we can't get the privileges and we don't use table/column grants. + + save_priv In this we store global and db level grants for the table + Note that we don't store db level grants if the global grants + is enough to satisfy the request. ****************************************************************************/ bool @@ -2559,7 +2567,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, if (!no_errors) net_printf(&thd->net,ER_ACCESS_DENIED_ERROR, thd->priv_user, - thd->host_or_ip, + thd->priv_host, thd->password ? ER(ER_YES) : ER(ER_NO));/* purecov: tested */ DBUG_RETURN(TRUE); /* purecov: tested */ } @@ -2584,7 +2592,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, if (!no_errors) net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR, thd->priv_user, - thd->host_or_ip, + thd->priv_host, db ? db : thd->db ? thd->db : "unknown"); /* purecov: tested */ DBUG_RETURN(TRUE); /* purecov: tested */ } @@ -3419,6 +3427,24 @@ void add_join_on(TABLE_LIST *b,Item *expr) } +/* + Mark that we have a NATURAL JOIN between two tables + + SYNOPSIS + add_join_natural() + a Table to do normal join with + b Do normal join with this table + + IMPLEMENTATION + This function just marks that table b should be joined with a. + The function setup_cond() will create in b->on_expr a list + of equal condition between all fields of the same name. + + SELECT * FROM t1 NATURAL LEFT JOIN t2 + <=> + SELECT * FROM t1 LEFT JOIN t2 ON (t1.i=t2.i and t1.j=t2.j ... ) +*/ + void add_join_natural(TABLE_LIST *a,TABLE_LIST *b) { b->natural_join=a; diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index d670c673b4a..283dd20a56c 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1042,6 +1042,9 @@ err: } send_eof(&thd->net); + pthread_mutex_lock(&LOCK_thread_count); + thd->current_linfo = 0; + pthread_mutex_unlock(&LOCK_thread_count); DBUG_RETURN(0); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f870f8f5178..79ba13a3339 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2631,6 +2631,9 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) join->thd->select_limit)) < 0) DBUG_RETURN(1); // Impossible range sel->cond=orig_cond; + /* Fix for EXPLAIN */ + if (sel->quick) + join->best_positions[i].records_read= sel->quick->records; } else { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index ec4f55f246d..94b37e164e7 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -23,6 +23,7 @@ #endif #include <hash.h> #include <myisam.h> +#include <my_dir.h> #include <assert.h> #ifdef __WIN__ @@ -1054,12 +1055,31 @@ static int prepare_for_repair(THD* thd, TABLE_LIST* table, } else { + /* + User gave us USE_FRM which means that the header in the index file is + trashed. + In this case we will try to fix the table the following way: + - Rename the data file to a temporary name + - Truncate the table + - Replace the new data file with the old one + - Run a normal repair using the new index file and the old data file + */ - char from[FN_REFLEN],tmp[FN_REFLEN]; - char* db = thd->db ? thd->db : table->db; + char from[FN_REFLEN],tmp[FN_REFLEN+32]; + const char **ext= table->table->file->bas_ext(); + MY_STAT stat_info; + + /* + Check if this is a table type that stores index and data separately, + like ISAM or MyISAM + */ + if (!ext[0] || !ext[1]) + DBUG_RETURN(0); // No data file + + strxmov(from, table->table->path, ext[1], NullS); // Name of data file + if (!my_stat(from, &stat_info, MYF(0))) + DBUG_RETURN(0); // Can't use USE_FRM flag - sprintf(from, "%s/%s/%s", mysql_real_data_home, db, table->real_name); - fn_format(from, from, "", MI_NAME_DEXT, 4); sprintf(tmp,"%s-%lx_%lx", from, current_pid, thd->thread_id); pthread_mutex_lock(&LOCK_open); @@ -1075,7 +1095,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST* table, unlock_table_name(thd, table); pthread_mutex_unlock(&LOCK_open); DBUG_RETURN(send_check_errmsg(thd, table, "repair", - "Failed renaming .MYD file")); + "Failed renaming data file")); } if (mysql_truncate(thd, table, 1)) { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 15917506ecf..f895c809366 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -492,12 +492,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %right NOT %right BINARY -/* These don't actually affect the way the query is really evaluated, but - they silence a few warnings for shift/reduce conflicts. */ -%left ',' -%left STRAIGHT_JOIN JOIN_SYM NATURAL -%nonassoc CROSS INNER_SYM LEFT RIGHT - %type <lex_str> IDENT TEXT_STRING REAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident ident_or_text @@ -2116,7 +2110,7 @@ join_table_list: | join_table_list ',' join_table_list { $$=$3; } | join_table_list normal_join join_table_list { $$=$3; } | join_table_list STRAIGHT_JOIN join_table_list - { $$=$3 ; $$->straight=1; } + { $$=$3 ; $1->next->straight=1; } | join_table_list normal_join join_table_list ON expr { add_join_on($3,$5); $$=$3; } | join_table_list normal_join join_table_list @@ -2140,9 +2134,13 @@ join_table_list: USING '(' using_list ')' { add_join_on($5,$9); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; } | join_table_list NATURAL LEFT opt_outer JOIN_SYM join_table_list - { add_join_natural($1,$6); $6->outer_join|=JOIN_TYPE_LEFT; $$=$6; } + { + add_join_natural($1,$1->next); + $1->next->outer_join|=JOIN_TYPE_LEFT; + $$=$6; + } | join_table_list RIGHT opt_outer JOIN_SYM join_table_list ON expr - { add_join_on($1,$7); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$1; } + { add_join_on($1,$7); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$5; } | join_table_list RIGHT opt_outer JOIN_SYM join_table_list { SELECT_LEX *sel=Select; @@ -2150,11 +2148,15 @@ join_table_list: sel->db2=$5->db; sel->table2=$5->alias; } USING '(' using_list ')' - { add_join_on($1,$9); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$1; } + { add_join_on($1,$9); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$5; } | join_table_list NATURAL RIGHT opt_outer JOIN_SYM join_table_list - { add_join_natural($6,$1); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$1; } + { + add_join_natural($1->next,$1); + $1->outer_join|=JOIN_TYPE_RIGHT; + $$=$6; + } | join_table_list NATURAL JOIN_SYM join_table_list - { add_join_natural($1,$4); $$=$4; }; + { add_join_natural($1,$1->next); $$=$4; }; normal_join: JOIN_SYM {} @@ -2308,16 +2310,12 @@ olap_opt: | WITH CUBE_SYM { LEX *lex=Lex; - lex->olap = true; - lex->select->olap= CUBE_TYPE; net_printf(&lex->thd->net, ER_NOT_SUPPORTED_YET, "CUBE"); YYABORT; /* To be deleted in 4.1 */ } | WITH ROLLUP_SYM { LEX *lex=Lex; - lex->olap = true; - lex->select->olap= ROLLUP_TYPE; net_printf(&lex->thd->net, ER_NOT_SUPPORTED_YET, "ROLLUP"); YYABORT; /* To be deleted in 4.1 */ } @@ -2405,7 +2403,7 @@ delete_limit_clause: ULONG_NUM: NUM { $$= strtoul($1.str,NULL,10); } - | LONG_NUM { $$= (ulonglong) strtoll($1.str,NULL,10); } + | LONG_NUM { $$= (ulong) strtoll($1.str,NULL,10); } | ULONGLONG_NUM { $$= (ulong) strtoull($1.str,NULL,10); } | REAL_NUM { $$= strtoul($1.str,NULL,10); } | FLOAT_NUM { $$= strtoul($1.str,NULL,10); }; diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh index 1e328a4f625..de01142beac 100644 --- a/support-files/mysql.server.sh +++ b/support-files/mysql.server.sh @@ -118,7 +118,18 @@ else test -z "$print_defaults" && print_defaults="my_print_defaults" fi -parse_arguments `$print_defaults mysqld mysql_server mysql.server` +# +# Test if someone changed datadir; In this case we should also read the +# default arguments from this directory +# + +extra_args="" +if test "$datadir" != "@localstatedir@" +then + extra_args="-e $datadir/my.cnf" +fi + +parse_arguments `$print_defaults $extra_args mysqld mysql_server mysql.server` # Safeguard (relative paths, core dumps..) cd $basedir diff --git a/tests/grant.pl b/tests/grant.pl index 5a24127d79d..e32431ad63a 100644 --- a/tests/grant.pl +++ b/tests/grant.pl @@ -63,6 +63,12 @@ user_connect(1); #goto test; # +# Enable column grant code +# +safe_query("grant select(user) on mysql.user to $user"); +safe_query("revoke select(user) on mysql.user from $user"); + +# # Test grants on user level # @@ -408,21 +414,29 @@ safe_query("grant ALL PRIVILEGES on $opt_database.test to $user identified by 'd user_connect(0,"dummy"); safe_query("grant SELECT on $opt_database.* to $user identified by ''"); user_connect(0); -safe_query("revoke ALL PRIVILEGES on $opt_database.test from $user identified by ''"); +safe_query("revoke ALL PRIVILEGES on $opt_database.test from $user identified by '', ${opt_user}\@127.0.0.1 identified by 'dummy2'"); safe_query("revoke ALL PRIVILEGES on $opt_database.* from $user identified by ''"); + safe_query("show grants for $user"); # # Test bug reported in SELECT INTO OUTFILE # -safe_query("create table $opt_database.test3 (a int)"); +safe_query("create table $opt_database.test3 (a int, b int)"); safe_query("grant SELECT on $opt_database.test3 to $user"); safe_query("grant FILE on *.* to $user"); -safe_query("insert into $opt_database.test3 values (1)"); +safe_query("insert into $opt_database.test3 values (1,1)"); user_connect(0); user_query("select * into outfile '$tmp_table' from $opt_database.test3"); safe_query("revoke SELECT on $opt_database.test3 from $user"); +safe_query("grant SELECT(a) on $opt_database.test3 to $user"); +user_query("select a from $opt_database.test3"); +user_query("select * from $opt_database.test3",1); +user_query("select a,b from $opt_database.test3",1); +user_query("select b from $opt_database.test3",1); + +safe_query("revoke SELECT(a) on $opt_database.test3 from $user"); safe_query("revoke FILE on *.* from $user"); safe_query("drop table $opt_database.test3"); diff --git a/tests/grant.res b/tests/grant.res index 92d271cd864..a50f73740c6 100644 --- a/tests/grant.res +++ b/tests/grant.res @@ -10,6 +10,8 @@ Error in execute: Can't drop database 'grant_test'. Database doesn't exist create database grant_test Connecting grant_user Error on connect: Access denied for user: '@localhost' to database 'grant_test' +grant select(user) on mysql.user to grant_user@localhost +revoke select(user) on mysql.user from grant_user@localhost grant select on *.* to grant_user@localhost set password FOR grant_user2@localhost = password('test') Error in execute: Can't find any matching row in the user table @@ -106,21 +108,21 @@ select count(*) from grant_test.test 2 select * from mysql.user where user = 'grant_user' -Error in execute: select command denied to user: 'grant_user@localhost' for table 'user' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql' insert into grant_test.test values (4,0) -Error in execute: insert command denied to user: 'grant_user@localhost' for table 'test' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test' update grant_test.test set a=1 -Error in execute: update command denied to user: 'grant_user@localhost' for table 'test' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test' delete from grant_test.test -Error in execute: delete command denied to user: 'grant_user@localhost' for table 'test' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test' create table grant_test.test2 (a int) -Error in execute: create command denied to user: 'grant_user@localhost' for table 'test2' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test' ALTER TABLE grant_test.test add c int -Error in execute: alter command denied to user: 'grant_user@localhost' for table 'test' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test' CREATE INDEX dummy ON grant_test.test (a) -Error in execute: index command denied to user: 'grant_user@localhost' for table 'test' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test' drop table grant_test.test -Error in execute: drop command denied to user: 'grant_user@localhost' for table 'test' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test' grant ALL PRIVILEGES on grant_test.* to grant_user2@localhost Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test' grant ALL PRIVILEGES on grant_test.* to grant_user@localhost WITH GRANT OPTION @@ -133,14 +135,14 @@ REVOKE ALL PRIVILEGES on grant_test.* from grant_user@localhost REVOKE ALL PRIVILEGES on grant_test.* from grant_user@localhost Connecting grant_user insert into grant_test.test values (6,0) -Error in execute: insert command denied to user: 'grant_user@localhost' for table 'test' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test' REVOKE GRANT OPTION on grant_test.* from grant_user@localhost Connecting grant_user Error on connect: Access denied for user: 'grant_user@localhost' to database 'grant_test' grant ALL PRIVILEGES on grant_test.* to grant_user@localhost Connecting grant_user select * from mysql.user where user = 'grant_user' -Error in execute: select command denied to user: 'grant_user@localhost' for table 'user' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql' insert into grant_test.test values (7,0) update grant_test.test set a=3 where a=2 delete from grant_test.test where a=3 @@ -152,7 +154,7 @@ show tables from grant_test test insert into mysql.user (host,user) values ('error','grant_user',0) -Error in execute: insert command denied to user: 'grant_user@localhost' for table 'user' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql' revoke ALL PRIVILEGES on grant_test.* from grant_user@localhost select * from mysql.user where user = 'grant_user' localhost grant_user N N N N N N N N N N N N N N N N N N N N N 0 0 0 @@ -200,7 +202,7 @@ Connecting grant_user update grant_test.test set b=b+1 revoke SELECT on *.* from grant_user@localhost Connecting grant_user -lect * from test +select * from test Error in execute: select command denied to user: 'grant_user@localhost' for table 'test' grant select on grant_test.test to grant_user@localhost delete from grant_test.test where a=1 @@ -233,7 +235,7 @@ Error in execute: select command denied to user: 'grant_user@localhost' for tabl select count(*) from test,test2 Error in execute: select command denied to user: 'grant_user@localhost' for table 'test2' replace into test2 SELECT a from test -Error in execute: update command denied to user: 'grant_user@localhost' for table 'test2' +Error in execute: delete command denied to user: 'grant_user@localhost' for table 'test2' grant update on grant_test.test2 to grant_user@localhost replace into test2 SELECT a,a from test Error in execute: delete command denied to user: 'grant_user@localhost' for table 'test2' @@ -448,21 +450,34 @@ grant ALL PRIVILEGES on grant_test.test to grant_user@localhost identified by 'd Connecting grant_user grant SELECT on grant_test.* to grant_user@localhost identified by '' Connecting grant_user -revoke ALL PRIVILEGES on grant_test.test from grant_user@localhost identified by '' +revoke ALL PRIVILEGES on grant_test.test from grant_user@localhost identified by '', grant_user@127.0.0.1 identified by 'dummy2' revoke ALL PRIVILEGES on grant_test.* from grant_user@localhost identified by '' show grants for grant_user@localhost -create table grant_test.test3 (a int) +GRANT USAGE ON *.* TO 'grant_user'@'localhost' + +create table grant_test.test3 (a int, b int) grant SELECT on grant_test.test3 to grant_user@localhost grant FILE on *.* to grant_user@localhost -insert into grant_test.test3 values (1) +insert into grant_test.test3 values (1,1) Connecting grant_user select * into outfile '/tmp/mysql-grant.test' from grant_test.test3 revoke SELECT on grant_test.test3 from grant_user@localhost +grant SELECT(a) on grant_test.test3 to grant_user@localhost +select a from grant_test.test3 +1 + +select * from grant_test.test3 +Error in execute: select command denied to user: 'grant_user@localhost' for column 'b' in table 'test3' +select a,b from grant_test.test3 +Error in execute: SELECT command denied to user: 'grant_user@localhost' for column 'b' in table 'test3' +select b from grant_test.test3 +Error in execute: SELECT command denied to user: 'grant_user@localhost' for column 'b' in table 'test3' +revoke SELECT(a) on grant_test.test3 from grant_user@localhost revoke FILE on *.* from grant_user@localhost drop table grant_test.test3 create table grant_test.test3 (a int) Connecting grant_user -Access denied for user: 'grant_user@localhost' to database 'grant_test' +Error on connect: Access denied for user: 'grant_user@localhost' to database 'grant_test' grant INSERT on grant_test.test3 to grant_user@localhost Connecting grant_user select * into outfile '/tmp/mysql-grant.test' from grant_test.test3 @@ -487,9 +502,11 @@ revoke SELECT,INSERT,UPDATE,DELETE on grant_test.test3 from grant_user@localhost Connecting grant_user revoke LOCK TABLES on *.* from grant_user@localhost Connecting grant_user -Access denied for user: 'grant_user@localhost' to database 'grant_test' +Error on connect: Access denied for user: 'grant_user@localhost' to database 'grant_test' drop table grant_test.test3 show grants for grant_user@localhost +GRANT USAGE ON *.* TO 'grant_user'@'localhost' + grant all on *.* to grant_user@localhost WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 2 MAX_CONNECTIONS_PER_HOUR 3 show grants for grant_user@localhost GRANT ALL PRIVILEGES ON *.* TO 'grant_user'@'localhost' WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 2 MAX_CONNECTIONS_PER_HOUR 3 @@ -501,6 +518,8 @@ GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, F revoke ALL PRIVILEGES on *.* from grant_user@localhost show grants for grant_user@localhost +GRANT USAGE ON *.* TO 'grant_user'@'localhost' WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 2 MAX_CONNECTIONS_PER_HOUR 3 + drop database grant_test delete from user where user='grant_user' delete from db where user='grant_user' diff --git a/vio/viossl.c b/vio/viossl.c index 0f34a45f9aa..834343a77d9 100644 --- a/vio/viossl.c +++ b/vio/viossl.c @@ -212,13 +212,14 @@ my_socket vio_ssl_fd(Vio* vio) } -my_bool vio_ssl_peer_addr(Vio * vio, char *buf) +my_bool vio_ssl_peer_addr(Vio * vio, char *buf, uint16 *port) { DBUG_ENTER("vio_ssl_peer_addr"); DBUG_PRINT("enter", ("sd=%d", vio->sd)); if (vio->localhost) { strmov(buf,"127.0.0.1"); + *port=0; } else { @@ -229,8 +230,13 @@ my_bool vio_ssl_peer_addr(Vio * vio, char *buf) DBUG_PRINT("exit", ("getpeername, error: %d", socket_errno)); DBUG_RETURN(1); } - /* FIXME */ -/* my_inet_ntoa(vio->remote.sin_addr,buf); */ +#ifdef TO_BE_FIXED + my_inet_ntoa(vio->remote.sin_addr,buf); + *port= 0; +#else + strmov(buf, "unknown"); + *port= 0; +#endif } DBUG_PRINT("exit", ("addr=%s", buf)); DBUG_RETURN(0); |