diff options
43 files changed, 3202 insertions, 854 deletions
diff --git a/BitKeeper/etc/collapsed b/BitKeeper/etc/collapsed index 311c3813abf..226f0f1a2e2 100644 --- a/BitKeeper/etc/collapsed +++ b/BitKeeper/etc/collapsed @@ -15,3 +15,5 @@ 45214442pBGT9KuZEGixBH71jTzbOA 45214a07hVsIGwvwa-WrO-jpeaSwVw 452a92d0-31-8wSzSfZi165fcGcXPA +454a7ef8gdvE_ddMlJyghvOAkKPNOQ +454f8960jsVT_kMKJtZ9OCgXoba0xQ diff --git a/Docs/MySQLEULA.txt b/Docs/MySQLEULA.txt deleted file mode 100644 index f50c50298b1..00000000000 --- a/Docs/MySQLEULA.txt +++ /dev/null @@ -1,252 +0,0 @@ - License Agreement for Commercial Use of MySQL[tm] Software - -This Agreement ("License") is between MySQL AB, a Swedish company -("Licensor"), and the customer ("Licensee") identified on the electronic order -form submitted on behalf of Licensee (the "Order Form"). In consideration of -the mutual promises, covenants and conditions contained herein, the -sufficiency of which is hereby acknowledged, the parties agree as follows. - -1. License Grant. -"Licensed Software" means a complete and unchanged copy of the object code -version of the MySQL relational database management software identified in the -Order Form and posted on a special download page of the MySQL AB web site (the -"Download Page") made available to Licensee immediately after payment as -provided in Section 4. Subject to payment and the other terms and conditions -hereof, Licensor grants to Licensee a limited, non-exclusive and -non-transferable right to: (a) make one copy of the Licensed Software for each -license purchased (each, a "Licensed Copy"); (b) compile and/or link each -Licensed Copy to one copy of the Licensee software identified in the Order -Form (the "Licensee Application") without modifying the Licensed Software -(each, an "Integrated Product"); and (c) load and use the Licensed Copy -portion of an Integrated Product on one machine or instrument in the operating -system environment(s), and on the hardware platform(s) specified in the Order -Form, and solely for running and extracting data from, the Licensee -Application. "Use" means operation by one person for internal business -purposes in accordance with the terms and conditions hereof. Licensed Copies -shall be deemed accepted by Licensee immediately upon download. Licensee may -make one additional copy of each Licensed Copy for backup and archival -purposes only. - -2. Transfer. -Only after Licensee has linked or compiled a Licensed Copy as permitted in -Section 1, Licensee may transfer to a third party (the "Transferee") the right -to use such copy as described in Section 1. As a condition to any such -transfer: (a) Licensee must deliver the Licensed Copy and any backup copy to -the Transferee along with a copy of this License (including the Sales Order); -and (b) the Transferee must accept the terms and conditions of this License. -Any and all of Licensee's rights to a Licensed Copy shall terminate upon -transfer of the right to use such copy. A Transferee's rights are limited to -the use rights described in Section 1(c), and do not include the linking, -compilation or copying rights (except for backup and archival copies) -described in Section 1. If you did not purchase this License directly from -MySQL AB, then you are a Transferee. Licensee and any Transferee must comply -with all applicable export laws and regulations. - -3. Restrictions. -Licensee may use the Licensed Software only as expressly provided in Section -1. Without limiting the foregoing, Licensee shall not: (a) lease, license, -use, make available, distribute or modify all or any part of the Licensed -Software to any third party, except as otherwise expressly permitted herein; -(b) use the Licensed Software to operate in or as a time-sharing, outsourcing, -service bureau, application service provider or managed service provider -environment; (c) lease, license, use, make available or distribute the -Licensed Software as a general SQL server, as a stand alone application or -with applications other than the Licensee Application under this License; (d) -copy the Licensed Software onto any public or distributed network; (e) -distribute Integrated Products pursuant to a public or open source license; -(f) port the Licensed Software to any operating system other than as described -in the Order Form; or (g) change any proprietary rights notices which appear -in the Licensed Software. Except as otherwise provided in Section 2, the -rights granted to Licensee herein are rights that may be exercised solely by -Licensee. - -4. Price and payment. -No later than thirty (30) days after submission of the Order Form, Licensee -shall remit one non-refundable license fee per Licensed Copy as posted on -http://shop.mysql.com on the date Licensee submitted the Order Form (the -"License Fee"). All payments shall be made in Euros or U.S. dollars. Licensee -shall be responsible for paying all local, state, federal and international -sales, value added, excise and other taxes and duties payable in connection -with this License, other than taxes based upon Licensor's net income. Licensee -shall not be permitted to access the Download Page until Licensor has received -payment in full. - -5. Termination. -Licensor may terminate this License immediately if the Licensee shall breach -any of the provisions of this License and such breach remains uncured 30 days -after receipt of notice. In the event that Licensee becomes liquidated, -dissolved, bankrupt or insolvent, whether voluntarily or involuntarily, or -shall take any action to be so declared, Licensor shall have the right to -terminate this License immediately. Upon expiration, cancellation or other -termination of this License, Licensee shall immediately: (a) discontinue -distribution of Integrated Products that include Licensed Software; and (b) -destroy all copies of the Licensed Software, including (without limitation) as -linked or compiled in any Integrated Product. Sections 4 through 10 shall -survive the termination of this License for any reason. - -6. Proprietary Rights. -Licensee agrees that the copyright, patent, trade secrets and all other -intellectual proprietary rights of whatever nature in the Licensed Software -and related documentation, including derivative works, are and shall remain -the exclusive property of Licensor and any third party suppliers. Nothing in -this License should be construed as transferring any aspects of such rights to -Licensee or any third party. Licensor reserves any and all rights not -expressly granted herein. MySQL is a trademark of MySQL AB, and shall not be -used by Licensee without Licensor's express written authorization. Licensee -shall include in the Integrated Products a conspicuous notice that the -Integrated Products include software whose copyright is owned by MySQL AB. - -7. Disclaimer of Warranties. -THE LICENSED SOFTWARE IS LICENSED "AS IS," WITHOUT ANY WARRANTIES WHATSOEVER. -LICENSOR EXPRESSLY DISCLAIMS, AND LICENSEE EXPRESSLY WAIVES, ALL WARRANTIES, -WHETHER EXPRESS OR IMPLIED, INCLUDING WARRANTIES OF MERCHANTIBILITY, FITNESS -FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, SYSTEM INTEGRATION, -NON-INTERFERENCE AND ACCURACY OF INFORMATIONAL CONTENT. LICENSOR DOES NOT -WARRANT THAT THE LICENSED SOFTWARE WILL MEET LICENSEE'S REQUIREMENTS OR THAT -THE OPERATION OF THE LICENSED SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR -THAT ERRORS WILL BE CORRECTED. THE ENTIRE RISK OF THE LICENSED SOFTWARE'S -QUALITY AND PERFORMANCE IS WITH LICENSEE. Without limiting the generality of -the foregoing disclaimer, Licensee acknowledges that the Licensed Software is -not specifically designed, manufactured or intended for use in the planning, -construction, maintenance, control or direct operation of nuclear facilities, -aircraft navigation, control or communication systems, weapons systems or -direct life support systems. - -8. Indemnification. -Licensee hereby indemnifies and agrees to defend Licensor against any and all -damages, judgments and costs (including reasonable attorneys' fees) related to -any claim based upon: (a) an allegation that the Licensee Application -infringes the intellectual property of a third party; (b) use of the Licensed -Software in a manner prohibited under this License or in a manner for which -the Licensed Software was not designed; (c) integration or use of the Licensed -Software with the Licensee Application (where use of the Licensed Software -alone would not infringe); (d) changes made by Licensee to the Licensed -Software (where use of unmodified Licensed Software would not infringe); (e) -changes made, or actions taken, by Licensor upon Licensee's direct -instructions; or (f) bodily injury, property damage or any other damage or -injury due to the use or inability to use an Integrated Product. - -9. Limitation of Liability. -LICENSOR SHALL HAVE NO LIABILITY WITH RESPECT TO ITS OBLIGATIONS UNDER THIS -AGREEMENT OR OTHERWISE FOR CONSEQUENTIAL, EXEMPLARY, SPECIAL, INDIRECT, -INCIDENTAL OR PUNITIVE DAMAGES, INCLUDING (WITHOUT LIMITATION) ANY LOST -PROFITS OR LOST SAVINGS (WHETHER RESULTING FROM IMPAIRED OR LOST DATA, -SOFTWARE OR COMPUTER FAILURE OR ANY OTHER CAUSE), EVEN IF IT HAS BEEN ADVISED -OF THE POSSIBILITY OF SUCH DAMAGES. NOTWITHSTANDING ANY OTHER PROVISION IN -THIS AGREEMENT, THE LIABILITY OF LICENSOR FOR ANY REASON AND UPON ANY CAUSE OF -ACTION SHALL BE LIMITED TO THE AMOUNT PAID TO LICENSOR BY LICENSEE UNDER THIS -AGREEMENT. THIS LIMITATION APPLIES TO ALL CAUSES OF ACTION IN THE AGGREGATE, -INCLUDING (WITHOUT LIMITATION) BREACH OF CONTRACT, BREACH OF WARRANTY, -NEGLIGENCE, MISREPRESENTATIONS AND OTHER TORTS. THE PARTIES AGREE THAT THE -REMEDIES AND LIMITATIONS HEREIN ALLOCATE THE RISKS BETWEEN THE PARTIES AS -AUTHORIZED BY APPLICABLE LAWS. THE LICENSE FEES ARE SET IN RELIANCE UPON THIS -ALLOCATION OF RISK AND THE EXCLUSION OF CERTAIN DAMAGES AS SET FORTH IN THIS -AGREEMENT. - -10. Miscellaneous. - -10.1 Interpretation. -Failure by Licensor to exercise any right or remedy does not signify -acceptance of the event giving rise to such right or remedy. No action arising -out of this License may be brought by Licensee more than one year after the -cause of action has accrued. If any part of this License is held by a court of -competent jurisdiction to be illegal or unenforceable, the validity or -enforceability of the remainder of this License shall not be affected and such -provision shall be deemed modified to the minimum extent necessary to make -such provision consistent with applicable law and, in its modified form, such -provision shall be enforceable and enforced. Licensor reserves the right not -to accept any Order Form. Any invoice issued by Licensor in connection with -this License shall be deemed a part of this Agreement. To the extent of any -inconsistency between an Order Form and an invoice issued by Licensor, the -terms and conditions of the invoice shall prevail; Licensee shall be deemed to -have accepted an invoice upon payment of such invoice. In the event that -Licensee placed an order by telephone or through an authorized sales -representative, the invoice issued by Licensor shall constitute the Order -Form. The terms and conditions of this Agreement shall replace and serve as a -novation of the terms and conditions of any commercial (i.e., non-GPL) license -purchased online by Licensee prior to August 2002. - -10.2 Binding. -This Agreement will be binding upon and inure to the benefit of the parties, -their respective successors and permitted assigns. Except as otherwise -provided in Section 2, without the prior written consent of Licensor, Licensee -may not assign this License or its rights or obligations under this License to -any person or party, whether by operation of law or otherwise; any attempt by -Licensee to assign this License without Licensor's prior written consent shall -be null and void. There are no intended third party beneficiaries of this -License. The parties are, and shall remain, independent contractors; nothing -in this License is designed to create, nor shall create between them, a -partnership, joint venture, agency, or employment relationship. - -10.3 Governing Law; Dispute Forum. -If Licensee's residence, principal place of business or place of organization -is in the United States of America ("USA"), then this License shall be deemed -to have been executed in the USA and shall be governed by the laws of the -State of Delaware, without regard to the conflict of laws provisions thereof. -If Licensee's residence, principal place of business or place of organization -is in any country other than the USA, then this License shall be deemed to -have been executed in Sweden and shall be governed by the laws of Sweden, -without regard to the conflict of laws provisions thereof. In no event shall -the United Nations Convention on Contracts for the International Sale of Goods -apply to, or govern, this License. The parties consent to the exclusive -jurisdiction of the courts of Sweden and the USA, as provided in this Section. -In the event that Licensor initiates an action in connection with this License -or any other dispute between the parties, the exclusive jurisdiction of such -action shall be in: (a) Newark, Delaware, if Licensee's residence, principal -place of business or place of organization is in the USA; or (b) Uppsala, -Sweden, if Licensee's residence, principal place of business or place of -organization is in any country other than the USA. In the event that Licensee -initiates an action in connection with this License or any other dispute -between the parties, the exclusive jurisdiction of such action shall be in -Stockholm, Sweden. Notwithstanding the foregoing, either party may bring a -counterclaim in an action in the same jurisdiction in which the originating -claim was filed, and either party may enforce any judgment rendered by such -court in any court of competent jurisdiction. Licensee shall comply at its own -expense with all relevant and applicable laws related to use and distribution -of the Licensed Software as permitted in this License. Notwithstanding the -foregoing, Licensor may seek injunctive or other equitable relief in any -jurisdiction in order to protect its intellectual property rights. The parties -have agreed to execute this License in the English language, and the English -language version of the Agreement will control for all purposes. Any action -brought under this License shall be conducted in the English language. -Licensee shall be responsible for Licensor's attorneys fees and other expenses -associated with the enforcement of this License or the collection of any -amounts due under this License. - -10.4 Notice. -Unless otherwise agreed, any notice under this License shall be delivered and -addressed to Licensee at the address set forth on the Order Form, and to -Licensor at Bangardsgatan 8, 753 20, Uppsala, Sweden. Notice shall be deemed -received by any party: (a) on the day given, if personally delivered or if -sent by confirmed facsimile transmission, receipt verified; (b) on the third -day after deposit, if mailed by certified, first class, postage prepaid, -return receipt requested mail, or by reputable, expedited overnight courier; -or (c) on the fifth day after deposit, if sent by reputable, expedited -international courier. Either party may change its address for notice -purposes upon notice in accordance with this Section. Licensor may identify -Licensee as a commercial licensee, including on the MySQL web site. - -10.5 GPL. -The GPL License shall continue to apply to any and all uses and distributions -of the Licensed Software undertaken by Licensee either prior to the Effective -Date, after termination, or otherwise outside the scope of this License. This -Agreement shall not be deemed to replace or otherwise amend any Licensee -rights or obligations pursuant to the GPL License with respect to any uses of -the Licensed Software described in the preceding sentence. - -10.6 Entire Agreement. -This Agreement (including the Order Form and the invoice) comprises the entire -agreement, and supercedes and merges all prior proposals, understandings and -agreements, oral and written, between the parties relating to the subject -matter of this License. This Agreement may be amended or modified only in a -writing executed by both parties. To the extent of any conflict or -inconsistency between this License and any invoice or other document submitted -by Licensee to Licensor, this License will control. Licensor's acceptance of -any document shall not be construed as an acceptance of provisions which are -in any way in conflict or inconsistent with, or in addition to, this License, -unless such terms are separately and specifically accepted in writing by an -authorized officer of Licensor. - -10.7 Print this License. -For record keeping purposes, we encourage Licensee to print this License and -the Order Form on the date that the Order Form is submitted. @@ -2,8 +2,9 @@ This is a release of MySQL, a dual-license SQL database server. MySQL is brought to you by the MySQL team at MySQL AB. License information can be found in these files: -- For GPL (free) distributions, see the COPYING file. -- For commercial distributions, see the MySQLEULA.txt file. +- For GPL (free) distributions, see the COPYING file and + the EXCEPTIONS-CLIENT file. +- For commercial distributions, see the LICENSE.mysql file. For further information about MySQL or additional documentation, see: @@ -15,11 +16,10 @@ Some manual sections of special interest: - If you are migrating from an older version of MySQL, please read the "Upgrading from..." section first! - To see what MySQL can do, take a look at the features section. -- For installation instructions, see the Installation chapter. -- For future plans, see the TODO appendix. -- For the new features/bugfix history, see the News appendix. -- For the currently known bugs/misfeatures (known errors) see the problems - appendix. +- For installation instructions, see the Installing and Upgrading chapter. +- For the new features/bugfix history, see the Change History appendix. +- For the currently known bugs/misfeatures (known errors) see the Problems + and Common Errors appendix. - For a list of developers and other contributors, see the Credits appendix. diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 6ec361392c8..e2b5931c2eb 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -16,21 +16,42 @@ #include "client_priv.h" #include <my_dir.h> +#include <my_list.h> +#include <sslopt-vars.h> + +#define UPGRADE_DEFAULTS_NAME "mysql_upgrade_defaults" +#define MYSQL_UPGRADE_INFO_NAME "mysql_upgrade_info" +#define MYSQL_FIX_PRIV_TABLES_NAME "mysql_fix_privilege_tables.sql" + +#define MY_PARENT (1 << 0) +#define MY_ISDIR (1 << 1) +#define MY_SEARCH_SELF (1 << 2) #ifdef __WIN__ const char *mysqlcheck_name= "mysqlcheck.exe"; const char *mysql_name= "mysql.exe"; +const char *mysqld_name= "mysqld.exe"; #else const char *mysqlcheck_name= "mysqlcheck"; const char *mysql_name= "mysql"; +const char *mysqld_name= "mysqld"; #endif /*__WIN__*/ -static my_bool opt_force= 0, opt_verbose= 0, tty_password= 0; +extern TYPELIB sql_protocol_typelib; + +static my_bool opt_force= 0, opt_verbose= 0, opt_compress= 0; static char *user= (char*) "root", *basedir= 0, *datadir= 0, *opt_password= 0; -static my_bool upgrade_defaults_created= 0; -static my_string opt_mysql_port, opt_mysql_unix_port= 0; -static char *default_dbug_option= (char*) "d:t:O,/tmp/comp_err.trace"; -static my_bool info_flag= 0; +static char *current_host= 0; +static char *opt_default_charset= 0, *opt_charsets_dir= 0; +#ifdef HAVE_SMEM +static char *shared_memory_base_name= 0; +#endif +static char *opt_protocol= 0; +static my_string opt_mysql_port= 0, opt_mysql_unix_port= 0; +#ifndef DBUG_OFF +static char *default_dbug_option= (char*) "d:t:O,/tmp/mysql_upgrade.trace"; +#endif +static my_bool info_flag= 0, tty_password= 0; static struct my_option my_long_options[]= { @@ -50,27 +71,51 @@ static struct my_option my_long_options[]= #endif {"debug-info", 'T', "Print some debug info at exit.", (gptr *) & info_flag, (gptr *) & info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"force", 'f', "Continue even if we get an sql-error.", + {"default-character-set", OPT_DEFAULT_CHARSET, + "Set the default character set.", (gptr*) &opt_default_charset, + (gptr*) &opt_default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"force", 'f', "Force execution of mysqlcheck even if mysql_upgrade " + "has already been executed for the current version of MySQL.", (gptr*) &opt_force, (gptr*) &opt_force, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"character-sets-dir", OPT_CHARSETS_DIR, + "Directory where character sets are.", (gptr*) &opt_charsets_dir, + (gptr*) &opt_charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"compress", OPT_COMPRESS, "Use compression in server/client protocol.", + (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, + 0, 0, 0}, + {"host",'h', "Connect to host.", (gptr*) ¤t_host, + (gptr*) ¤t_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"password", 'p', - "Password to use when connecting to server. If password is not given it's solicited on the tty.", - 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + "Password to use when connecting to server. If password is not given" + " it's solicited on the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, +#ifdef __WIN__ + {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, +#endif {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port, - (gptr*) &opt_mysql_port, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, - 0}, + (gptr*) &opt_mysql_port, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#ifdef HAVE_SMEM + {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME, + "Base name of shared memory.", (gptr*) &shared_memory_base_name, + (gptr*) &shared_memory_base_name, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#endif {"socket", 'S', "Socket file to use for connection.", - (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR, - REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"user", 'u', "User for login if not current user.", (gptr*) &user, (gptr*) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"verbose", 'v', "Display more output about the process", (gptr*) &opt_verbose, - (gptr *) &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, +#include <sslopt-longopts.h> + {"verbose", 'v', "Display more output about the process", + (gptr*) &opt_verbose, (gptr*) &opt_verbose, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; + static const char *load_default_groups[]= { "mysql_upgrade", 0 @@ -78,6 +123,81 @@ static const char *load_default_groups[]= #include <help_end.h> +static LIST *extra_defaults= NULL; + +typedef struct _extra_default +{ + int id; + const char *name; + int n_len; + const char *value; + int v_len; +} extra_default_t; + +static inline +void set_extra_default(int id, const struct my_option *opt) +{ + switch (id) { + case 'b': case 'd': /* these are ours */ + case 'f': /* --force is ours */ + case 'u': /* --user passed on cmdline */ + case 'T': /* --debug-info is not accepted by mysqlcheck */ + /* so, do nothing */ + break; + default: + { + LIST *l; + extra_default_t *d; + + /* + Remove any earlier duplicates: they can + refer to invalid memory addresses (stale pointers) + */ + l= extra_defaults; + while (l) + { + LIST *n= l->next; + + d= l->data; + if (d->id == id) + { + extra_defaults= list_delete(extra_defaults, l); + my_free((gptr)l, MYF(0)); + my_free((gptr)d, MYF(0)); + } + l= n; + } + + d= (extra_default_t *)my_malloc(sizeof(extra_default_t), + MYF(MY_FAE|MY_ZEROFILL)); + d->id= id; + d->name= opt->name; + d->n_len= strlen(opt->name); + if (opt->arg_type != NO_ARG) + switch (opt->var_type & GET_TYPE_MASK) { + case GET_BOOL: + if (*((int *)opt->value)) + { + d->value= "true"; + d->v_len= 4; + } + break; + case GET_STR: + case GET_STR_ALLOC: + d->value= *opt->value; + d->v_len= strlen(d->value); + break; + default: + my_printf_error(0, "Error: internal error at %s:%d", MYF(0), + __FILE__, __LINE__); + exit(1); + } + list_push(extra_defaults, d); + } + } +} + + static my_bool get_one_option(int optid, const struct my_option *opt __attribute__ ((unused)), char *argument) @@ -85,16 +205,13 @@ get_one_option(int optid, const struct my_option *opt __attribute__ ((unused)), switch (optid) { case '?': puts - ("MySQL utility script to upgrade database to the current server version"); + ("MySQL utility to upgrade database to the current server version"); puts(""); my_print_help(my_long_options); exit(0); case '#': DBUG_PUSH(argument ? argument : default_dbug_option); break; - case 'f': - opt_force= TRUE; - break; case 'p': tty_password= 1; if (argument) @@ -109,315 +226,410 @@ get_one_option(int optid, const struct my_option *opt __attribute__ ((unused)), tty_password= 0; } break; +#ifdef __WIN__ + case 'W': + my_free(opt_protocol, MYF(MY_ALLOW_ZERO_PTR)); + opt_protocol= my_strdup("pipe", MYF(MY_FAE)); + break; +#endif + case OPT_MYSQL_PROTOCOL: + if (find_type(argument, &sql_protocol_typelib, 0) > 0) + { + my_free(opt_protocol, MYF(MY_ALLOW_ZERO_PTR)); + opt_protocol= my_strdup(argument, MYF(MY_FAE)); + } + else + { + fprintf(stderr, "Unknown option to protocol: %s\n", argument); + exit(1); + } + break; +#include <sslopt-case.h> default:; - }; + } + set_extra_default(opt->id, opt); return 0; } -/* buffer should be not smaller than FN_REFLEN */ -static my_bool test_file_exists_res(const char *dir, const char *fname, - char *buffer, char **buf_end) -{ - MY_STAT stat_info; - - *buf_end= strxnmov(buffer, FN_REFLEN-1, dir, "/", fname, NullS); - unpack_filename(buffer, buffer); - return my_stat(buffer, &stat_info, MYF(0)) != 0; -} - - -static my_bool test_file_exists(const char *dir, const char *fname) -{ - char path[FN_REFLEN]; - char *path_end; - return test_file_exists_res(dir, fname, path, &path_end); -} - - static int create_check_file(const char *path) { - File check_file= my_open(path, O_CREAT | O_WRONLY, MYF(MY_FAE | MY_WME)); - int error; - - if (check_file < 0) - return 1; - - error= my_write(check_file, - MYSQL_SERVER_VERSION, strlen(MYSQL_SERVER_VERSION), + int ret; + File fd; + + fd= my_open(path, O_CREAT | O_WRONLY, MYF(MY_FAE | MY_WME)); + if (fd < 0) { + ret= 1; + goto error; + } + ret= my_write(fd, MYSQL_SERVER_VERSION, + sizeof(MYSQL_SERVER_VERSION) - 1, MYF(MY_WME | MY_FNABP)); - error= my_close(check_file, MYF(MY_FAE | MY_WME)) || error; - return error; + ret|= my_close(fd, MYF(MY_FAE | MY_WME)); +error: + return ret; } -static int create_defaults_file(const char *path, const char *our_defaults_path) +static int create_defaults_file(const char *path, const char *forced_path) { - uint b_read; - File our_defaults_file, defaults_file; - char buffer[512]; - char *buffer_end; - int failed_to_open_count= 0; - int error; - - /* check if the defaults file is needed at all */ - if (!opt_password) - return 0; - -retry_open: + int ret; + uint cnt; + File forced_file, defaults_file; + + DYNAMIC_STRING buf; + extra_default_t *d; + + my_delete(path, MYF(0)); + defaults_file= my_open(path, O_BINARY | O_CREAT | O_WRONLY | O_EXCL, MYF(MY_FAE | MY_WME)); - if (defaults_file < 0) { - if (failed_to_open_count == 0) - { - remove(path); - failed_to_open_count+= 1; - goto retry_open; - } - else - return 1; + ret= 1; + goto out; + } + + if (init_dynamic_string(&buf, NULL, my_getpagesize(), FN_REFLEN)) + { + ret= 1; + goto error; } - upgrade_defaults_created= 1; - if (our_defaults_path) + if (forced_path) { - our_defaults_file= my_open(our_defaults_path, O_RDONLY, - MYF(MY_FAE | MY_WME)); - if (our_defaults_file < 0) - return 1; + forced_file= my_open(forced_path, O_RDONLY, MYF(MY_FAE | MY_WME)); + if (forced_file < 0) + { + ret= 1; + goto error; + } do { - if (((b_read= my_read(our_defaults_file, buffer, - sizeof(buffer), MYF(MY_WME))) == MY_FILE_ERROR) || - my_write(defaults_file, buffer, b_read, MYF(MY_FNABP | MY_WME))) + cnt= my_read(forced_file, buf.str, buf.max_length, MYF(MY_WME)); + if ((cnt == MY_FILE_ERROR) + || my_write(defaults_file, buf.str, cnt, MYF(MY_FNABP | MY_WME))) { - error= 1; - goto close_return; + ret= 1; + my_close(forced_file, MYF(0)); + goto error; } - } while (b_read == sizeof(buffer)); + } while (cnt == buf.max_length); + my_close(forced_file, MYF(0)); } - buffer_end= strnmov(buffer, "\n[client]", sizeof(buffer)); - if (opt_password) - buffer_end= strxnmov(buffer_end, sizeof(buffer), - "\npassword=", opt_password, NullS); - error= my_write(defaults_file, buffer, (int) (buffer_end - buffer), - MYF(MY_WME | MY_FNABP)); -close_return: - return my_close(defaults_file, MYF(MY_WME)) || error; + + dynstr_set(&buf, "\n[client]"); + while (extra_defaults) + { + int len; + + d= extra_defaults->data; + len= d->n_len + d->v_len + 1; + if (buf.length + len >= buf.max_length) /* to avoid realloc() */ + { + if (my_write(defaults_file, buf.str, buf.length, MYF(MY_FNABP | MY_WME))) + { + ret= 1; + goto error; + } + dynstr_set(&buf, NULL); + } + if (dynstr_append_mem(&buf, "\n", 1) + || dynstr_append_mem(&buf, d->name, d->n_len) + || (d->v_len && (dynstr_append_mem(&buf, "=", 1) + || dynstr_append_mem(&buf, d->value, d->v_len)))) + { + ret= 1; + goto error; + } + my_delete((gptr)d, MYF(0)); + list_pop(extra_defaults); /* pop off the head */ + } + if (my_write(defaults_file, buf.str, buf.length, MYF(MY_FNABP | MY_WME))) + { + ret= 1; + goto error; + } + /* everything's all right */ + ret= 0; +error: + dynstr_free(&buf); + + if (defaults_file >= 0) + ret|= my_close(defaults_file, MYF(MY_WME)); + + if (ret) + my_delete(path, MYF(0)); + +out: + return ret; +} + + +/* Compare filenames */ +static int comp_names(struct fileinfo *a, struct fileinfo *b) +{ + return (strcmp(a->name,b->name)); +} + + +static int +find_file(const char *name, const char *root, uint flags, char *result, size_t len, ...) +{ + int ret; + va_list va; + FILEINFO key= { (char*)name, NULL }; + const char *subdir; + char *cp; + + DBUG_ASSERT(root != NULL); + + cp= strmake(result, root, len); + if (cp[-1] != FN_LIBCHAR) + *cp++= FN_LIBCHAR; + + ret= 1; + va_start(va, len); + subdir= (!(flags & MY_SEARCH_SELF)) ? va_arg(va, char *) : ""; + while (subdir) + { + MY_DIR *dir; + FILEINFO *match; + char *cp1; + + cp1= strnmov(cp, subdir, len - (cp - result) - 1); + + dir= my_dir(result, (flags & MY_ISDIR) ? MY_WANT_STAT : MYF(0)); + if (dir) + { + match= bsearch(&key, dir->dir_entry, dir->number_off_files, + sizeof(FILEINFO), (qsort_cmp)comp_names); + if (match) + { + ret= (flags & MY_ISDIR) ? !MY_S_ISDIR(match->mystat->st_mode) : 0; + if (!ret) + { + if (cp1[-1] != FN_LIBCHAR) + *cp1++= FN_LIBCHAR; + + if (!(flags & MY_PARENT)) + strnmov(cp1, name, len - (cp1 - result)); + else + *cp1= '\0'; + + my_dirend(dir); + break; + } + } + my_dirend(dir); + } + subdir= va_arg(va, char *); + } + va_end(va); + return ret; } int main(int argc, char **argv) { - char bindir[FN_REFLEN]; - char *bindir_end, *buf_end; - char datadir_buf[FN_REFLEN]; - char mysqlcheck_line[FN_REFLEN], *mysqlcheck_end; - char check_file_name[FN_REFLEN]; - int check_file; - char fix_priv_tables_cmd[FN_REFLEN], *fix_cmd_end; - char script_line[FN_REFLEN]; - int error; + int ret; + char *forced_defaults_file; char *forced_extra_defaults; char *defaults_group_suffix; - char upgrade_defaults_path[FN_REFLEN], *defaults_to_use= 0; - char port_socket[100], *port_socket_end; + const char *script_line; + char *upgrade_defaults_path; + char *defaults_to_use= NULL; + int upgrade_defaults_created= 0; + + char path[FN_REFLEN]; + DYNAMIC_STRING cmdline; MY_INIT(argv[0]); #ifdef __NETWARE__ setscreenmode(SCR_AUTOCLOSE_ON_EXIT); #endif + /* Check if we are forced to use specific defaults */ + get_defaults_options(argc, argv, + &forced_defaults_file, &forced_extra_defaults, + &defaults_group_suffix); + load_defaults("my", load_default_groups, &argc, &argv); - if ((error= handle_options(&argc, &argv, my_long_options, get_one_option))) - exit(error); - + if (handle_options(&argc, &argv, my_long_options, get_one_option)) + { + ret= 1; + goto error; + } if (tty_password) opt_password= get_tty_password(NullS); - /* Check if we want to force the use a specific default file */ - get_defaults_options(argc, argv, - &forced_defaults_file, &forced_extra_defaults, - &defaults_group_suffix); - - port_socket_end= port_socket; - if (opt_mysql_port) - port_socket_end= strxnmov(port_socket, sizeof(port_socket) - 1, " --port=", - opt_mysql_port, NullS); - if (opt_mysql_unix_port) - port_socket_end= strxnmov(port_socket_end, - sizeof(port_socket) - - (int)(port_socket_end - port_socket) - 1, - " --socket=", opt_mysql_unix_port, NullS); - *port_socket_end= 0; - - if (basedir) + if (init_dynamic_string(&cmdline, NULL, 2 * FN_REFLEN + 128, FN_REFLEN)) { - bindir_end= strmake(bindir, basedir, sizeof(bindir)-1); + ret= 1; + goto error; } - else + if (!basedir) { - if (test_file_exists("./share/mysql/english", "errmsg.sys") - && (test_file_exists("./bin", "mysqld") || - test_file_exists("./libexec", "mysqld"))) - { - my_getwd(bindir, sizeof(bindir), MYF(0)); - bindir_end= bindir + strlen(bindir); - } - else + my_getwd(path, sizeof(path), MYF(0)); + basedir= my_strdup(path, MYF(0)); + if (find_file("errmsg.sys", basedir, MYF(0), path, sizeof(path), + "share/mysql/english", NullS) + || find_file(mysqld_name, basedir, MYF(0), path, sizeof(path), + "bin", "libexec", NullS)) { - bindir_end= strmake(bindir, DEFAULT_MYSQL_HOME, sizeof(bindir)-1); + my_free((gptr)basedir, MYF(0)); + basedir= (char *)DEFAULT_MYSQL_HOME; } } if (!datadir) { - datadir= datadir_buf; - if (test_file_exists(bindir, "data/mysql")) - { - *strxnmov(datadir_buf, sizeof(datadir_buf)-1, bindir, "/data", NullS)= 0; - } - else if (test_file_exists(bindir, "var/mysql")) - { - *strxnmov(datadir_buf, sizeof(datadir_buf)-1, bindir, "/var", NullS)= 0; - } + if (!find_file("mysql", basedir, MYF(MY_ISDIR|MY_PARENT), + path, sizeof(path), + "data", "var", NullS)) + datadir= my_strdup(path, MYF(0)); else - datadir= (char*) DATADIR; + datadir= (char *)DATADIR; } - - strmake(bindir_end, "/bin", sizeof(bindir) - (int) (bindir_end - bindir)-1); - - if (!test_file_exists_res - (bindir, mysqlcheck_name, mysqlcheck_line, &mysqlcheck_end)) + if (find_file("user.frm", datadir, MYF(0), path, sizeof(path), + "mysql", NullS)) { - printf("Can't find program '%s'\n", mysqlcheck_line); - puts("Please restart with --basedir=mysql-install-directory"); - exit(1); + ret= 1; + puts("Can't find data directory. Please restart with" + " --datadir=path-to-writable-data-dir"); + goto error; } - if (!test_file_exists(datadir, "mysql/user.frm")) + /* + Create the modified defaults file to be used by mysqlcheck + and mysql tools + */ + fn_format(path, UPGRADE_DEFAULTS_NAME, datadir, "", MYF(0)); + upgrade_defaults_path= my_strdup(path, MYF(0)); + + if (extra_defaults) { - puts - ("Can't find data directory. Please restart with --datadir=path-to-data-dir"); - exit(1); - } - - /* create the modified defaults file to be used by mysqlcheck */ - /* and mysql tools */ - *strxnmov(upgrade_defaults_path, sizeof(upgrade_defaults_path)-1, - datadir, "/upgrade_defaults", NullS)= 0; - unpack_filename(upgrade_defaults_path, upgrade_defaults_path); - if ((error= - create_defaults_file(upgrade_defaults_path, forced_extra_defaults))) - goto err_exit; - - defaults_to_use= upgrade_defaults_created ? - upgrade_defaults_path : forced_extra_defaults; + ret= create_defaults_file(upgrade_defaults_path, forced_extra_defaults); + if (ret) + goto error; + + defaults_to_use= upgrade_defaults_path; + upgrade_defaults_created= 1; + } + else + defaults_to_use= forced_extra_defaults; - if (test_file_exists_res(datadir, "mysql_upgrade_info", check_file_name, - &buf_end) && !opt_force) + if (!find_file(MYSQL_UPGRADE_INFO_NAME, datadir, MY_SEARCH_SELF, + path, sizeof(path), NULL, NullS) + && !opt_force) { - char chf_buffer[50]; - int b_read; - check_file= my_open(check_file_name, O_RDONLY, MYF(0)); - b_read= my_read(check_file, chf_buffer, sizeof(chf_buffer)-1, MYF(0)); - chf_buffer[b_read]= 0; - my_close(check_file, MYF(0)); - if (!strcmp(chf_buffer, MYSQL_SERVER_VERSION)) + char buf[sizeof(MYSQL_SERVER_VERSION)]; + int fd, cnt; + + fd= my_open(path, O_RDONLY, MYF(0)); + cnt= my_read(fd, buf, sizeof(buf) - 1, MYF(0)); + my_close(fd, MYF(0)); + buf[cnt]= 0; + if (!strcmp(buf, MYSQL_SERVER_VERSION)) { if (opt_verbose) - puts("mysql_upgrade already done for this version"); + puts("mysql_upgrade has already been done for this version"); goto fix_priv_tables; } } + + if (find_file(mysqlcheck_name, basedir, MYF(0), path, sizeof(path), + "bin", NullS)) + { + ret= 1; + printf("Can't find program '%s'\n", mysqlcheck_name); + puts("Please restart with --basedir=mysql-install-directory"); + goto error; + } + else + dynstr_set(&cmdline, path); if (defaults_to_use) { - mysqlcheck_end= strxnmov(mysqlcheck_end, - sizeof(mysqlcheck_line) - (int) (mysqlcheck_end - - mysqlcheck_line), - " --defaults-extra-file=", defaults_to_use,NullS); + dynstr_append(&cmdline, " --defaults-extra-file="); + dynstr_append(&cmdline, defaults_to_use); } - - mysqlcheck_end= strxnmov(mysqlcheck_end, - sizeof(mysqlcheck_line) - - (int) (mysqlcheck_end - mysqlcheck_line - 1), - " --check-upgrade --all-databases --auto-repair --user=", - user, port_socket, NullS); - *mysqlcheck_end= 0; + + dynstr_append(&cmdline, " --check-upgrade --all-databases" + " --auto-repair --user="); + dynstr_append(&cmdline, user); if (opt_verbose) - printf("Running %s\n", mysqlcheck_line); - if ((error= system(mysqlcheck_line))) + printf("Running %s\n", cmdline.str); + + ret= system(cmdline.str); + if (ret) { - printf("Error executing '%s'\n", mysqlcheck_line); - goto err_exit; + printf("Error executing '%s'\n", cmdline.str); + goto error; } - if ((error= create_check_file(check_file_name))) - goto err_exit; + fn_format(path, MYSQL_UPGRADE_INFO_NAME, datadir, "", MYF(0)); + ret= create_check_file(path); + if (ret) + goto error; fix_priv_tables: - if (!test_file_exists_res(bindir, mysql_name, - fix_priv_tables_cmd, &fix_cmd_end)) + if (find_file(mysql_name, basedir, MYF(0), path, sizeof(path), + "bin", NullS)) { - puts("Could not find MySQL command-line client (mysql)."); - puts - ("Please use --basedir to specify the directory where MySQL is installed."); - error= 1; - goto err_exit; + ret= 1; + puts("Could not find MySQL command-line client (mysql).\n" + "Please use --basedir to specify the directory" + " where MySQL is installed."); + goto error; } - - if (!test_file_exists_res(basedir, - "support_files/mysql_fix_privilege_tables.sql", - script_line, &buf_end) - && !test_file_exists_res(basedir, "share/mysql_fix_privilege_tables.sql", - script_line, &buf_end) - && !test_file_exists_res(basedir, - "share/mysql/mysql_fix_privilege_tables.sql", - script_line, &buf_end) - && !test_file_exists_res(basedir, - "scripts/mysql_fix_privilege_tables.sql", - script_line, &buf_end) - && !test_file_exists_res("/usr/local/mysql/share/mysql", - "mysql_fix_privilege_tables.sql", script_line, - &buf_end)) + else + dynstr_set(&cmdline, path); + + if (find_file(MYSQL_FIX_PRIV_TABLES_NAME, basedir, MYF(0), + path, sizeof(path), + "support_files", "share/mysql", "scripts", + NullS) + && find_file(MYSQL_FIX_PRIV_TABLES_NAME, "/usr/local/mysql", MYF(0), + path, sizeof(path), + "share/mysql", NullS)) { - puts("Could not find file mysql_fix_privilege_tables.sql"); - puts - ("Please use --basedir to specify the directory where MySQL is installed"); - error= 1; - goto err_exit; + ret= 1; + puts("Could not find file " MYSQL_FIX_PRIV_TABLES_NAME "\n" + "Please use --basedir to specify the directory" + " where MySQL is installed"); + goto error; } + else + script_line= my_strdup(path, MYF(0)); if (defaults_to_use) { - fix_cmd_end= strxnmov(fix_cmd_end, - sizeof(fix_priv_tables_cmd) - - (int) (fix_cmd_end - fix_priv_tables_cmd - 1), - " --defaults-extra-file=", defaults_to_use, NullS); + dynstr_append(&cmdline, " --defaults-extra-file="); + dynstr_append(&cmdline, defaults_to_use); } - fix_cmd_end= strxnmov(fix_cmd_end, - sizeof(fix_priv_tables_cmd) - (int) (fix_cmd_end - - fix_priv_tables_cmd), - " --user=", user, port_socket, " mysql < ", script_line, NullS); - *fix_cmd_end= 0; + dynstr_append(&cmdline, " --force --no-auto-rehash --batch --user="); + dynstr_append(&cmdline, user); + dynstr_append(&cmdline, " mysql < "); + dynstr_append(&cmdline, script_line); - if ((error= system(fix_priv_tables_cmd))) - { - /* Problem is that the 'Duplicate column' error */ - /* which is not a bug for the script makes 'mysql' return */ - /* an error */ - /* printf("Error executing '%s'\n", fix_priv_tables_cmd); */ - } + if (opt_verbose) + printf("Running %s\n", cmdline.str); + + ret= system(cmdline.str); + if (ret) + printf("Error executing '%s'\n", cmdline.str); + +error: + dynstr_free(&cmdline); -err_exit: if (upgrade_defaults_created) my_delete(upgrade_defaults_path, MYF(0)); + my_end(info_flag ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); - return error; -} /* main */ + return ret; +} + diff --git a/client/mysqltest.c b/client/mysqltest.c index aeb86575333..561bc541c74 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -80,13 +80,13 @@ enum { OPT_SSL_CA, OPT_SSL_CAPATH, OPT_SSL_CIPHER, OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL, OPT_SSL_VERIFY_SERVER_CERT, OPT_MAX_CONNECT_RETRIES, - OPT_MARK_PROGRESS + OPT_MARK_PROGRESS, OPT_CHARSETS_DIR }; static int record= 0, opt_sleep= -1; static char *db= 0, *pass= 0; const char *user= 0, *host= 0, *unix_sock= 0, *opt_basedir= "./"; -const char *opt_include= 0; +const char *opt_include= 0, *opt_charsets_dir; static int port= 0; static int opt_max_connect_retries; static my_bool opt_compress= 0, silent= 0, verbose= 0; @@ -145,7 +145,6 @@ static struct st_test_file* file_stack_end; static CHARSET_INFO *charset_info= &my_charset_latin1; /* Default charset */ -static const char *charset_name= "latin1"; /* Default character set name */ static const char *embedded_server_groups[]= { @@ -3093,7 +3092,11 @@ void do_connect(struct st_command *command) if (opt_compress || con_compress) mysql_options(&next_con->mysql, MYSQL_OPT_COMPRESS, NullS); mysql_options(&next_con->mysql, MYSQL_OPT_LOCAL_INFILE, 0); - mysql_options(&next_con->mysql, MYSQL_SET_CHARSET_NAME, charset_name); + mysql_options(&next_con->mysql, MYSQL_SET_CHARSET_NAME, + charset_info->csname); + if (opt_charsets_dir) + mysql_options(&cur_con->mysql, MYSQL_SET_CHARSET_DIR, + opt_charsets_dir); #ifdef HAVE_OPENSSL if (opt_use_ssl || con_ssl) @@ -3779,6 +3782,9 @@ static struct my_option my_long_options[] = 0, 0, 0, 0, 0, 0}, {"basedir", 'b', "Basedir for tests.", (gptr*) &opt_basedir, (gptr*) &opt_basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"character-sets-dir", OPT_CHARSETS_DIR, + "Directory where character sets are.", (gptr*) &opt_charsets_dir, + (gptr*) &opt_charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"compress", 'C', "Use the compressed server/client protocol.", (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -5511,7 +5517,11 @@ int main(int argc, char **argv) if (opt_compress) mysql_options(&cur_con->mysql,MYSQL_OPT_COMPRESS,NullS); mysql_options(&cur_con->mysql, MYSQL_OPT_LOCAL_INFILE, 0); - mysql_options(&cur_con->mysql, MYSQL_SET_CHARSET_NAME, charset_name); + mysql_options(&cur_con->mysql, MYSQL_SET_CHARSET_NAME, + charset_info->csname); + if (opt_charsets_dir) + mysql_options(&cur_con->mysql, MYSQL_SET_CHARSET_DIR, + opt_charsets_dir); #ifdef HAVE_OPENSSL diff --git a/configure.in b/configure.in index 8dffddbeb30..d0c2cd87381 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 5.0.29) +AM_INIT_AUTOMAKE(mysql, 5.0.30) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 @@ -19,7 +19,7 @@ SHARED_LIB_VERSION=$SHARED_LIB_MAJOR_VERSION:0:0 # ndb version NDB_VERSION_MAJOR=5 NDB_VERSION_MINOR=0 -NDB_VERSION_BUILD=29 +NDB_VERSION_BUILD=30 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? diff --git a/include/abi_check b/include/abi_check new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/include/abi_check diff --git a/include/abi_check.ic b/include/abi_check.ic new file mode 100644 index 00000000000..30ef44a1ccb --- /dev/null +++ b/include/abi_check.ic @@ -0,0 +1,914 @@ +struct rand_struct; +struct st_list; +struct st_mem_root; +struct st_mysql; +struct st_mysql_bind; +struct st_mysql_data; +struct st_mysql_field; +struct st_mysql_manager; +struct st_mysql_methods; +struct st_mysql_options; +struct st_mysql_parameters; +struct st_mysql_res; +struct st_mysql_rows; +struct st_mysql_stmt; +struct st_mysql_time; +struct st_net; +struct st_typelib; +struct st_udf_args; +struct st_udf_init; +struct st_used_mem; +enum Item_result; +enum enum_field_types; +enum enum_mysql_set_option; +enum enum_mysql_stmt_state; +enum enum_mysql_timestamp_type; +enum enum_server_command; +enum enum_stmt_attr_type; +enum mysql_enum_shutdown_level; +enum mysql_option; +enum mysql_protocol_type; +enum mysql_rpl_type; +enum mysql_status; +# 131 "mysql.h" +typedef struct st_mysql_rows MYSQL_ROWS; +# 24 "my_list.h" +typedef struct st_list LIST; +# 232 "mysql.h" +typedef struct st_mysql MYSQL; +# 571 "mysql.h" +typedef struct st_mysql_bind MYSQL_BIND; +# 93 "mysql.h" +typedef struct st_mysql_field MYSQL_FIELD; +# 117 "mysql.h" +typedef unsigned int MYSQL_FIELD_OFFSET; +# 323 "mysql.h" +typedef struct st_mysql_manager MYSQL_MANAGER; +# 337 "mysql.h" +typedef struct st_mysql_parameters MYSQL_PARAMETERS; +# 292 "mysql.h" +typedef struct st_mysql_res MYSQL_RES; +# 116 "mysql.h" +typedef char * * MYSQL_ROW; +# 137 "mysql.h" +typedef MYSQL_ROWS * MYSQL_ROW_OFFSET; +# 596 "mysql.h" +typedef struct st_mysql_stmt MYSQL_STMT; +# 151 "mysql_com.h" +typedef struct st_net NET; +# 21 "typelib.h" +typedef struct st_typelib TYPELIB; +# 141 "mysql_com.h" +typedef struct st_vio Vio; +# 57 "mysql.h" +typedef char * gptr; +# 29 "my_list.h" +typedef int (* list_walk_action)(void *, void *); +# 48 "mysql.h" +typedef char my_bool; +# 63 "mysql.h" +typedef int my_socket; +# 125 "mysql.h" +typedef unsigned long long int my_ulonglong; +# 35 "my_alloc.h" +typedef struct st_mem_root MEM_ROOT; +# 141 "mysql.h" +typedef struct st_mysql_data MYSQL_DATA; +# 648 "mysql.h" +typedef struct st_mysql_methods MYSQL_METHODS; +# 48 "mysql_time.h" +typedef struct st_mysql_time MYSQL_TIME; +# 315 "mysql_com.h" +typedef struct st_udf_args UDF_ARGS; +# 326 "mysql_com.h" +typedef struct st_udf_init UDF_INIT; +# 27 "my_alloc.h" +typedef struct st_used_mem USED_MEM; +# 302 "mysql_com.h" +struct __attribute__((aligned(__alignof__(unsigned long int)), aligned(__alignof__(double)))) rand_struct + { + unsigned long int seed1; + unsigned long int seed2; + unsigned long int max_value; + double max_value_dbl; + }; +# 24 "my_list.h" +struct __attribute__((aligned(__alignof__(void *)))) st_list + { + struct st_list * prev; + struct st_list * next; + void * data; + }; +# 35 "my_alloc.h" +struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned int)))) st_mem_root + { + USED_MEM * free; + USED_MEM * used; + USED_MEM * pre_alloc; + unsigned int min_malloc; + unsigned int block_size; + unsigned int block_num; + unsigned int first_block_usage; + void (* error_handler)(void); + }; +# 232 "mysql.h" +struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long long int)))) st_mysql + { + NET net; + gptr connector_fd; + char * host; + char * user; + char * passwd; + char * unix_socket; + char * server_version; + char * host_info; + char * info; + char * db; + struct charset_info_st * charset; + MYSQL_FIELD * fields; + MEM_ROOT field_alloc; + my_ulonglong affected_rows; + my_ulonglong insert_id; + my_ulonglong extra_info; + unsigned long int thread_id; + unsigned long int packet_length; + unsigned int port; + unsigned long int client_flag; + unsigned long int server_capabilities; + unsigned int protocol_version; + unsigned int field_count; + unsigned int server_status; + unsigned int server_language; + unsigned int warning_count; + struct st_mysql_options options; + enum mysql_status status; + my_bool free_me; + my_bool reconnect; + char scramble[(20 + 1)]; + my_bool rpl_pivot; + struct st_mysql * master; + struct st_mysql * next_slave; + struct st_mysql * last_used_slave; + struct st_mysql * last_used_con; + LIST * stmts; + struct st_mysql_methods const * methods; + void * thd; + my_bool * unbuffered_fetch_owner; + struct st_mysql_stmt * current_stmt; + }; +# 571 "mysql.h" +struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_mysql_bind + { + unsigned long int * length; + my_bool * is_null; + void * buffer; + enum enum_field_types buffer_type; + unsigned long int buffer_length; + unsigned char * inter_buffer; + unsigned long int offset; + unsigned long int internal_length; + unsigned int param_number; + unsigned int pack_length; + my_bool is_unsigned; + my_bool long_data_used; + my_bool internal_is_null; + void (* store_param_func)(NET * net, struct st_mysql_bind * param); + void (* fetch_result)(struct st_mysql_bind *, unsigned char * * row); + void (* skip_result)(struct st_mysql_bind *, MYSQL_FIELD *, unsigned char * * row); + }; +# 141 "mysql.h" +struct __attribute__((aligned(__alignof__(unsigned long long int)), aligned(__alignof__(void *)))) st_mysql_data + { + my_ulonglong rows; + unsigned int fields; + MYSQL_ROWS * data; + MEM_ROOT alloc; + MYSQL_ROWS * * prev_ptr; + }; +# 93 "mysql.h" +struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_mysql_field + { + char * name; + char * org_name; + char * table; + char * org_table; + char * db; + char * catalog; + char * def; + unsigned long int length; + unsigned long int max_length; + unsigned int name_length; + unsigned int org_name_length; + unsigned int table_length; + unsigned int org_table_length; + unsigned int db_length; + unsigned int catalog_length; + unsigned int def_length; + unsigned int flags; + unsigned int decimals; + unsigned int charsetnr; + enum enum_field_types type; + }; +# 323 "mysql.h" +struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_mysql_manager + { + NET net; + char * host; + char * user; + char * passwd; + unsigned int port; + my_bool free_me; + my_bool eof; + int cmd_status; + int last_errno; + char * net_buf; + char * net_buf_pos; + char * net_data_end; + int net_buf_size; + char last_error[256]; + }; +# 648 "mysql.h" +struct __attribute__((aligned(__alignof__(void *)))) st_mysql_methods + { + my_bool (* read_query_result)(MYSQL * mysql); + my_bool (* advanced_command)(MYSQL * mysql, enum enum_server_command, char const * header, unsigned long int, char const * arg, unsigned long int, my_bool, MYSQL_STMT * stmt); + MYSQL_DATA * (* read_rows)(MYSQL * mysql, MYSQL_FIELD * mysql_fields, unsigned int); + MYSQL_RES * (* use_result)(MYSQL * mysql); + void (* fetch_lengths)(unsigned long int * to, MYSQL_ROW, unsigned int); + void (* flush_use_result)(MYSQL * mysql); + MYSQL_FIELD * (* list_fields)(MYSQL * mysql); + my_bool (* read_prepare_result)(MYSQL * mysql, MYSQL_STMT * stmt); + int (* stmt_execute)(MYSQL_STMT * stmt); + int (* read_binary_rows)(MYSQL_STMT * stmt); + int (* unbuffered_fetch)(MYSQL * mysql, char * * row); + void (* free_embedded_thd)(MYSQL * mysql); + char const * (* read_statistics)(MYSQL * mysql); + my_bool (* next_result)(MYSQL * mysql); + int (* read_change_user_result)(MYSQL * mysql, char * buff, char const * passwd); + }; +# 162 "mysql.h" +struct __attribute__((aligned(__alignof__(unsigned long int)), aligned(__alignof__(void *)))) st_mysql_options + { + unsigned int connect_timeout; + unsigned int read_timeout; + unsigned int write_timeout; + unsigned int port; + unsigned int protocol; + unsigned long int client_flag; + char * host; + char * user; + char * password; + char * unix_socket; + char * db; + struct st_dynamic_array * init_commands; + char * my_cnf_file; + char * my_cnf_group; + char * charset_dir; + char * charset_name; + char * ssl_key; + char * ssl_cert; + char * ssl_ca; + char * ssl_capath; + char * ssl_cipher; + char * shared_memory_base_name; + unsigned long int max_allowed_packet; + my_bool use_ssl; + my_bool compress; + my_bool named_pipe; + my_bool rpl_probe; + my_bool rpl_parse; + my_bool no_master_reads; + my_bool separate_thread; + enum mysql_option methods_to_use; + char * client_ip; + my_bool secure_auth; + int (* local_infile_init)(void * *, char const *, void *); + int (* local_infile_read)(void *, char *, unsigned int); + void (* local_infile_end)(void); + int (* local_infile_error)(void *, char *, unsigned int); + void * local_infile_userdata; + }; +# 337 "mysql.h" +struct __attribute__((aligned(__alignof__(void *)))) st_mysql_parameters + { + unsigned long int * p_max_allowed_packet; + unsigned long int * p_net_buffer_length; + }; +# 292 "mysql.h" +struct __attribute__((aligned(__alignof__(unsigned long long int)), aligned(__alignof__(void *)))) st_mysql_res + { + my_ulonglong row_count; + MYSQL_FIELD * fields; + MYSQL_DATA * data; + MYSQL_ROWS * data_cursor; + unsigned long int * lengths; + MYSQL * handle; + MEM_ROOT field_alloc; + unsigned int field_count; + unsigned int current_field; + MYSQL_ROW row; + MYSQL_ROW current_row; + my_bool eof; + my_bool unbuffered_fetch_cancelled; + struct st_mysql_methods const * methods; + }; +# 131 "mysql.h" +struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_mysql_rows + { + struct st_mysql_rows * next; + MYSQL_ROW data; + unsigned long int length; + }; +# 596 "mysql.h" +struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long long int)))) st_mysql_stmt + { + MEM_ROOT mem_root; + LIST list; + MYSQL * mysql; + MYSQL_BIND * params; + MYSQL_BIND * bind; + MYSQL_FIELD * fields; + MYSQL_DATA result; + MYSQL_ROWS * data_cursor; + my_ulonglong affected_rows; + my_ulonglong insert_id; + int (* read_row_func)(struct st_mysql_stmt * stmt, unsigned char * * row); + unsigned long int stmt_id; + unsigned int last_errno; + unsigned int param_count; + unsigned int field_count; + enum enum_mysql_stmt_state state; + char last_error[512]; + char sqlstate[(5 + 1)]; + my_bool send_types_to_server; + my_bool bind_param_done; + my_bool bind_result_done; + my_bool unbuffered_fetch_cancelled; + my_bool update_max_length; + }; +# 48 "mysql_time.h" +struct __attribute__((aligned(__alignof__(unsigned long int)))) st_mysql_time + { + unsigned int year; + unsigned int month; + unsigned int day; + unsigned int hour; + unsigned int minute; + unsigned int second; + unsigned long int second_part; + my_bool neg; + enum enum_mysql_timestamp_type time_type; + }; +# 151 "mysql_com.h" +struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_net + { + Vio * vio; + unsigned char * buff; + unsigned char * buff_end; + unsigned char * write_pos; + unsigned char * read_pos; + my_socket fd; + unsigned long int max_packet; + unsigned long int max_packet_size; + unsigned int pkt_nr; + unsigned int compress_pkt_nr; + unsigned int write_timeout; + unsigned int read_timeout; + unsigned int retry_count; + int fcntl; + my_bool compress; + unsigned long int remain_in_buf; + unsigned long int length; + unsigned long int buf_length; + unsigned long int where_b; + unsigned int * return_status; + unsigned char reading_or_writing; + char save_char; + my_bool no_send_ok; + char last_error[512]; + char sqlstate[(5 + 1)]; + unsigned int last_errno; + unsigned char error; + gptr query_cache_query; + my_bool report_error; + my_bool return_errno; + }; +# 21 "typelib.h" +struct __attribute__((aligned(__alignof__(unsigned int)), aligned(__alignof__(void *)))) st_typelib + { + unsigned int count; + char const * name; + char const * * type_names; + unsigned int * type_lengths; + }; +# 315 "mysql_com.h" +struct __attribute__((aligned(__alignof__(unsigned int)), aligned(__alignof__(void *)))) st_udf_args + { + unsigned int arg_count; + enum Item_result * arg_type; + char * * args; + unsigned long int * lengths; + char * maybe_null; + }; +# 326 "mysql_com.h" +struct __attribute__((aligned(__alignof__(unsigned long int)), aligned(__alignof__(void *)))) st_udf_init + { + my_bool maybe_null; + unsigned int decimals; + unsigned long int max_length; + char * ptr; + my_bool const_item; + }; +# 27 "my_alloc.h" +struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned int)))) st_used_mem + { + struct st_used_mem * next; + unsigned int left; + unsigned int size; + }; +# 313 "mysql_com.h" +enum Item_result + { + STRING_RESULT = 0, + REAL_RESULT = 1, + INT_RESULT = 2, + ROW_RESULT = 3, + }; +# 186 "mysql_com.h" +enum enum_field_types + { + MYSQL_TYPE_DECIMAL = 0, + MYSQL_TYPE_TINY = 1, + MYSQL_TYPE_SHORT = 2, + MYSQL_TYPE_LONG = 3, + MYSQL_TYPE_FLOAT = 4, + MYSQL_TYPE_DOUBLE = 5, + MYSQL_TYPE_NULL = 6, + MYSQL_TYPE_TIMESTAMP = 7, + MYSQL_TYPE_LONGLONG = 8, + MYSQL_TYPE_INT24 = 9, + MYSQL_TYPE_DATE = 10, + MYSQL_TYPE_TIME = 11, + MYSQL_TYPE_DATETIME = 12, + MYSQL_TYPE_YEAR = 13, + MYSQL_TYPE_NEWDATE = 14, + MYSQL_TYPE_ENUM = 247, + MYSQL_TYPE_SET = 248, + MYSQL_TYPE_TINY_BLOB = 249, + MYSQL_TYPE_MEDIUM_BLOB = 250, + MYSQL_TYPE_LONG_BLOB = 251, + MYSQL_TYPE_BLOB = 252, + MYSQL_TYPE_VAR_STRING = 253, + MYSQL_TYPE_STRING = 254, + MYSQL_TYPE_GEOMETRY = 255, + }; +# 269 "mysql_com.h" +enum enum_mysql_set_option + { + MYSQL_OPTION_MULTI_STATEMENTS_ON = 0, + MYSQL_OPTION_MULTI_STATEMENTS_OFF = 1, + }; +# 563 "mysql.h" +enum enum_mysql_stmt_state + { + MYSQL_STMT_INIT_DONE = 1, + MYSQL_STMT_PREPARE_DONE = 2, + MYSQL_STMT_EXECUTE_DONE = 3, + MYSQL_STMT_FETCH_DONE = 4, + }; +# 29 "mysql_time.h" +enum enum_mysql_timestamp_type + { + MYSQL_TIMESTAMP_NONE = -(2), + MYSQL_TIMESTAMP_ERROR = -(1), + MYSQL_TIMESTAMP_DATE = 0, + MYSQL_TIMESTAMP_DATETIME = 1, + MYSQL_TIMESTAMP_TIME = 2, + }; +# 39 "mysql_com.h" +enum enum_server_command + { + COM_SLEEP = 0, + COM_QUIT = 1, + COM_INIT_DB = 2, + COM_QUERY = 3, + COM_FIELD_LIST = 4, + COM_CREATE_DB = 5, + COM_DROP_DB = 6, + COM_REFRESH = 7, + COM_SHUTDOWN = 8, + COM_STATISTICS = 9, + COM_PROCESS_INFO = 10, + COM_CONNECT = 11, + COM_PROCESS_KILL = 12, + COM_DEBUG = 13, + COM_PING = 14, + COM_TIME = 15, + COM_DELAYED_INSERT = 16, + COM_CHANGE_USER = 17, + COM_BINLOG_DUMP = 18, + COM_TABLE_DUMP = 19, + COM_CONNECT_OUT = 20, + COM_REGISTER_SLAVE = 21, + COM_PREPARE = 22, + COM_EXECUTE = 23, + COM_LONG_DATA = 24, + COM_CLOSE_STMT = 25, + COM_RESET_STMT = 26, + COM_SET_OPTION = 27, + COM_END = 28, + }; +# 635 "mysql.h" +enum enum_stmt_attr_type + { + STMT_ATTR_UPDATE_MAX_LENGTH = 0, + }; +# 244 "mysql_com.h" +enum mysql_enum_shutdown_level + { + SHUTDOWN_DEFAULT = 0, + SHUTDOWN_WAIT_CONNECTIONS = (unsigned char)((1 << 0)), + SHUTDOWN_WAIT_TRANSACTIONS = (unsigned char)((1 << 1)), + SHUTDOWN_WAIT_UPDATES = (unsigned char)((1 << 3)), + SHUTDOWN_WAIT_ALL_BUFFERS = ((unsigned char)((1 << 3)) << 1), + SHUTDOWN_WAIT_CRITICAL_BUFFERS = (((unsigned char)((1 << 3)) << 1) + 1), + KILL_CONNECTION = 255, + }; +# 151 "mysql.h" +enum mysql_option + { + MYSQL_OPT_CONNECT_TIMEOUT = 0, + MYSQL_OPT_COMPRESS = 1, + MYSQL_OPT_NAMED_PIPE = 2, + MYSQL_INIT_COMMAND = 3, + MYSQL_READ_DEFAULT_FILE = 4, + MYSQL_READ_DEFAULT_GROUP = 5, + MYSQL_SET_CHARSET_DIR = 6, + MYSQL_SET_CHARSET_NAME = 7, + MYSQL_OPT_LOCAL_INFILE = 8, + MYSQL_OPT_PROTOCOL = 9, + MYSQL_SHARED_MEMORY_BASE_NAME = 10, + MYSQL_OPT_READ_TIMEOUT = 11, + MYSQL_OPT_WRITE_TIMEOUT = 12, + MYSQL_OPT_USE_RESULT = 13, + MYSQL_OPT_USE_REMOTE_CONNECTION = 14, + MYSQL_OPT_USE_EMBEDDED_CONNECTION = 15, + MYSQL_OPT_GUESS_CONNECTION = 16, + MYSQL_SET_CLIENT_IP = 17, + MYSQL_SECURE_AUTH = 18, + }; +# 214 "mysql.h" +enum mysql_protocol_type + { + MYSQL_PROTOCOL_DEFAULT = 0, + MYSQL_PROTOCOL_TCP = 1, + MYSQL_PROTOCOL_SOCKET = 2, + MYSQL_PROTOCOL_PIPE = 3, + MYSQL_PROTOCOL_MEMORY = 4, + }; +# 224 "mysql.h" +enum mysql_rpl_type + { + MYSQL_RPL_MASTER = 0, + MYSQL_RPL_SLAVE = 1, + MYSQL_RPL_ADMIN = 2, + }; +# 209 "mysql.h" +enum mysql_status + { + MYSQL_STATUS_READY = 0, + MYSQL_STATUS_GET_RESULT = 1, + MYSQL_STATUS_USE_RESULT = 2, + }; +# 365 "mysql_com.h" +extern my_bool check_scramble(char const * reply, char const * message, unsigned char const * hash_stage2); +# 358 "mysql_com.h" +extern my_bool check_scramble_323(char const *, char const * message, unsigned long int * salt); +# 353 "mysql_com.h" +extern void create_random_string(char * to, unsigned int, struct rand_struct * rand_st); +# 28 "typelib.h" +extern int find_type(char * x, TYPELIB * typelib, unsigned int); +# 367 "mysql_com.h" +extern void get_salt_from_password(unsigned char * res, char const * password); +# 360 "mysql_com.h" +extern void get_salt_from_password_323(unsigned long int * res, char const * password); +# 372 "mysql_com.h" +extern char * get_tty_password(char * opt_message); +# 30 "typelib.h" +extern char const * get_type(TYPELIB * typelib, unsigned int); +# 355 "mysql_com.h" +extern void hash_password(unsigned long int * to, char const * password, unsigned int); +# 31 "my_list.h" +extern LIST * list_add(LIST * root, LIST * element); +# 33 "my_list.h" +extern LIST * list_cons(void * data, LIST * root); +# 32 "my_list.h" +extern LIST * list_delete(LIST * root, LIST * element); +# 35 "my_list.h" +extern void list_free(LIST * root, unsigned int); +# 36 "my_list.h" +extern unsigned int list_length(LIST *); +# 34 "my_list.h" +extern LIST * list_reverse(LIST * root); +# 37 "my_list.h" +extern int list_walk(LIST *, list_walk_action, gptr); +# 378 "mysql_com.h" +extern int load_defaults(char const * conf_file, char const * * groups, int * argc, char * * * argv); +# 368 "mysql_com.h" +extern void make_password_from_salt(char * to, unsigned char const * hash_stage2); +# 361 "mysql_com.h" +extern void make_password_from_salt_323(char * to, unsigned long int const * salt); +# 363 "mysql_com.h" +extern void make_scrambled_password(char * to, char const * password); +# 356 "mysql_com.h" +extern void make_scrambled_password_323(char * to, char const * password); +# 29 "typelib.h" +extern void make_type(char * to, unsigned int, TYPELIB * typelib); +# 299 "mysql_com.h" +extern int my_connect(my_socket, struct sockaddr const * name, unsigned int, unsigned int); +# 377 "mysql_com.h" +extern my_bool my_init(void); +# 281 "mysql_com.h" +extern my_bool my_net_init(NET * net, Vio * vio); +# 282 "mysql_com.h" +extern void my_net_local_init(NET * net); +# 292 "mysql_com.h" +extern unsigned long int my_net_read(NET * net); +# 287 "mysql_com.h" +extern my_bool my_net_write(NET * net, char const * packet, unsigned long int); +# 352 "mysql_com.h" +extern double my_rnd(struct rand_struct *); +# 381 "mysql_com.h" +extern void my_thread_end(void); +# 380 "mysql_com.h" +extern my_bool my_thread_init(void); +# 539 "mysql.h" +extern void myodbc_remove_escape(MYSQL * mysql, char * name); +# 481 "mysql.h" +extern int mysql_add_slave(MYSQL * mysql, char const * host, unsigned int, char const * user, char const * passwd); +# 393 "mysql.h" +extern my_ulonglong mysql_affected_rows(MYSQL * mysql); +# 720 "mysql.h" +extern my_bool mysql_autocommit(MYSQL * mysql, my_bool); +# 408 "mysql.h" +extern my_bool mysql_change_user(MYSQL * mysql, char const * user, char const * passwd, char const * db); +# 401 "mysql.h" +extern char const * mysql_character_set_name(MYSQL * mysql); +# 723 "mysql.h" +extern void mysql_close(MYSQL * sock); +# 718 "mysql.h" +extern my_bool mysql_commit(MYSQL * mysql); +# 510 "mysql.h" +extern void mysql_data_seek(MYSQL_RES * result, my_ulonglong); +# 528 "mysql.h" +extern void mysql_debug(char const * debug); +# 467 "mysql.h" +extern void mysql_disable_reads_from_master(MYSQL * mysql); +# 461 "mysql.h" +extern void mysql_disable_rpl_parse(MYSQL * mysql); +# 489 "mysql.h" +extern int mysql_dump_debug_info(MYSQL * mysql); +# 541 "mysql.h" +extern my_bool mysql_embedded(void); +# 466 "mysql.h" +extern void mysql_enable_reads_from_master(MYSQL * mysql); +# 460 "mysql.h" +extern void mysql_enable_rpl_parse(MYSQL * mysql); +# 385 "mysql.h" +extern my_bool mysql_eof(MYSQL_RES * res); +# 395 "mysql.h" +extern unsigned int mysql_errno(MYSQL * mysql); +# 373 "mysql_com.h" +extern char const * mysql_errno_to_sqlstate(unsigned int); +# 396 "mysql.h" +extern char const * mysql_error(MYSQL * mysql); +# 521 "mysql.h" +extern unsigned long int mysql_escape_string(char * to, char const * from, unsigned long int); +# 518 "mysql.h" +extern MYSQL_FIELD * mysql_fetch_field(MYSQL_RES * result); +# 386 "mysql.h" +extern MYSQL_FIELD * mysql_fetch_field_direct(MYSQL_RES * res, unsigned int); +# 388 "mysql.h" +extern MYSQL_FIELD * mysql_fetch_fields(MYSQL_RES * res); +# 517 "mysql.h" +extern unsigned long int * mysql_fetch_lengths(MYSQL_RES * result); +# 516 "mysql.h" +extern MYSQL_ROW mysql_fetch_row(MYSQL_RES * result); +# 392 "mysql.h" +extern unsigned int mysql_field_count(MYSQL * mysql); +# 514 "mysql.h" +extern MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES * result, MYSQL_FIELD_OFFSET); +# 390 "mysql.h" +extern MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES * res); +# 509 "mysql.h" +extern void mysql_free_result(MYSQL_RES * result); +# 499 "mysql.h" +extern char const * mysql_get_client_info(void); +# 500 "mysql.h" +extern unsigned long int mysql_get_client_version(void); +# 501 "mysql.h" +extern char const * mysql_get_host_info(MYSQL * mysql); +# 367 "mysql.h" +extern MYSQL_PARAMETERS * mysql_get_parameters(void); +# 503 "mysql.h" +extern unsigned int mysql_get_proto_info(MYSQL * mysql); +# 498 "mysql.h" +extern char const * mysql_get_server_info(MYSQL * mysql); +# 502 "mysql.h" +extern unsigned long int mysql_get_server_version(MYSQL * mysql); +# 523 "mysql.h" +extern unsigned long int mysql_hex_string(char * to, char const * from, unsigned long int); +# 399 "mysql.h" +extern char const * mysql_info(MYSQL * mysql); +# 404 "mysql.h" +extern MYSQL * mysql_init(MYSQL * mysql); +# 394 "mysql.h" +extern my_ulonglong mysql_insert_id(MYSQL * mysql); +# 492 "mysql.h" +extern int mysql_kill(MYSQL * mysql, unsigned long int); +# 504 "mysql.h" +extern MYSQL_RES * mysql_list_dbs(MYSQL * mysql, char const * wild); +# 519 "mysql.h" +extern MYSQL_RES * mysql_list_fields(MYSQL * mysql, char const * table, char const * wild); +# 506 "mysql.h" +extern MYSQL_RES * mysql_list_processes(MYSQL * mysql); +# 505 "mysql.h" +extern MYSQL_RES * mysql_list_tables(MYSQL * mysql, char const * wild); +# 548 "mysql.h" +extern void mysql_manager_close(MYSQL_MANAGER * con); +# 549 "mysql.h" +extern int mysql_manager_command(MYSQL_MANAGER * con, char const * cmd, int); +# 543 "mysql.h" +extern MYSQL_MANAGER * mysql_manager_connect(MYSQL_MANAGER * con, char const * host, char const * user, char const * passwd, unsigned int); +# 551 "mysql.h" +extern int mysql_manager_fetch_line(MYSQL_MANAGER * con, char * res_buf, int); +# 542 "mysql.h" +extern MYSQL_MANAGER * mysql_manager_init(MYSQL_MANAGER * con); +# 427 "mysql.h" +extern my_bool mysql_master_query(MYSQL * mysql, char const * q, unsigned long int); +# 429 "mysql.h" +extern my_bool mysql_master_send_query(MYSQL * mysql, char const * q, unsigned long int); +# 721 "mysql.h" +extern my_bool mysql_more_results(MYSQL * mysql); +# 722 "mysql.h" +extern int mysql_next_result(MYSQL * mysql); +# 384 "mysql.h" +extern unsigned int mysql_num_fields(MYSQL_RES * res); +# 383 "mysql.h" +extern my_ulonglong mysql_num_rows(MYSQL_RES * res); +# 529 "mysql.h" +extern char * mysql_odbc_escape_string(MYSQL * mysql, char * to, unsigned long int, char const * from, unsigned long int, void * param, char * (* extend_buffer)(void *, char * to, unsigned long int * length)); +# 507 "mysql.h" +extern int mysql_options(MYSQL * mysql, enum mysql_option, char const * arg); +# 496 "mysql.h" +extern int mysql_ping(MYSQL * mysql); +# 75 "mysql.h" +extern unsigned int mysql_port; +# 418 "mysql.h" +extern int mysql_query(MYSQL * mysql, char const * q); +# 554 "mysql.h" +extern my_bool mysql_read_query_result(MYSQL * mysql); +# 469 "mysql.h" +extern my_bool mysql_reads_from_master_enabled(MYSQL * mysql); +# 410 "mysql.h" +extern MYSQL * mysql_real_connect(MYSQL * mysql, char const * host, char const * user, char const * passwd, char const * db, unsigned int, char const * unix_socket, unsigned long int); +# 525 "mysql.h" +extern unsigned long int mysql_real_escape_string(MYSQL * mysql, char * to, char const * from, unsigned long int); +# 421 "mysql.h" +extern int mysql_real_query(MYSQL * mysql, char const * q, unsigned long int); +# 490 "mysql.h" +extern int mysql_refresh(MYSQL * mysql, unsigned int); +# 719 "mysql.h" +extern my_bool mysql_rollback(MYSQL * mysql); +# 512 "mysql.h" +extern MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES * result, MYSQL_ROW_OFFSET); +# 389 "mysql.h" +extern MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES * res); +# 463 "mysql.h" +extern int mysql_rpl_parse_enabled(MYSQL * mysql); +# 474 "mysql.h" +extern my_bool mysql_rpl_probe(MYSQL * mysql); +# 471 "mysql.h" +extern enum mysql_rpl_type mysql_rpl_query_type(char const * q, int); +# 417 "mysql.h" +extern int mysql_select_db(MYSQL * mysql, char const * db); +# 419 "mysql.h" +extern int mysql_send_query(MYSQL * mysql, char const * q, unsigned long int); +# 354 "mysql.h" +extern void mysql_server_end(void); +# 353 "mysql.h" +extern int mysql_server_init(int, char * * argv, char * * groups); +# 402 "mysql.h" +extern int mysql_set_character_set(MYSQL * mysql, char const * csname); +# 452 "mysql.h" +extern void mysql_set_local_infile_default(MYSQL * mysql); +# 441 "mysql.h" +extern void mysql_set_local_infile_handler(MYSQL * mysql, int (* local_infile_init)(void * *, char const *, void *), int (* local_infile_read)(void *, char *, unsigned int), void (* local_infile_end)(void), int (* local_infile_error)(void *, char *, unsigned int), void *); +# 477 "mysql.h" +extern int mysql_set_master(MYSQL * mysql, char const * host, unsigned int, char const * user, char const * passwd); +# 493 "mysql.h" +extern int mysql_set_server_option(MYSQL * mysql, enum enum_mysql_set_option); +# 486 "mysql.h" +extern int mysql_shutdown(MYSQL * mysql, enum mysql_enum_shutdown_level); +# 432 "mysql.h" +extern my_bool mysql_slave_query(MYSQL * mysql, char const * q, unsigned long int); +# 434 "mysql.h" +extern my_bool mysql_slave_send_query(MYSQL * mysql, char const * q, unsigned long int); +# 397 "mysql.h" +extern char const * mysql_sqlstate(MYSQL * mysql); +# 405 "mysql.h" +extern my_bool mysql_ssl_set(MYSQL * mysql, char const * key, char const * cert, char const * ca, char const * capath, char const * cipher); +# 497 "mysql.h" +extern char const * mysql_stat(MYSQL * mysql); +# 714 "mysql.h" +extern my_ulonglong mysql_stmt_affected_rows(MYSQL_STMT * stmt); +# 692 "mysql.h" +extern my_bool mysql_stmt_attr_get(MYSQL_STMT * stmt, enum enum_stmt_attr_type, void * attr); +# 689 "mysql.h" +extern my_bool mysql_stmt_attr_set(MYSQL_STMT * stmt, enum enum_stmt_attr_type, void const * attr); +# 695 "mysql.h" +extern my_bool mysql_stmt_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bnd); +# 696 "mysql.h" +extern my_bool mysql_stmt_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bnd); +# 697 "mysql.h" +extern my_bool mysql_stmt_close(MYSQL_STMT * stmt); +# 712 "mysql.h" +extern void mysql_stmt_data_seek(MYSQL_STMT * stmt, my_ulonglong); +# 706 "mysql.h" +extern unsigned int mysql_stmt_errno(MYSQL_STMT * stmt); +# 707 "mysql.h" +extern char const * mysql_stmt_error(MYSQL_STMT * stmt); +# 682 "mysql.h" +extern int mysql_stmt_execute(MYSQL_STMT * stmt); +# 683 "mysql.h" +extern int mysql_stmt_fetch(MYSQL_STMT * stmt); +# 684 "mysql.h" +extern int mysql_stmt_fetch_column(MYSQL_STMT * stmt, MYSQL_BIND * bind, unsigned int, unsigned long int); +# 716 "mysql.h" +extern unsigned int mysql_stmt_field_count(MYSQL_STMT * stmt); +# 699 "mysql.h" +extern my_bool mysql_stmt_free_result(MYSQL_STMT * stmt); +# 679 "mysql.h" +extern MYSQL_STMT * mysql_stmt_init(MYSQL * mysql); +# 715 "mysql.h" +extern my_ulonglong mysql_stmt_insert_id(MYSQL_STMT * stmt); +# 713 "mysql.h" +extern my_ulonglong mysql_stmt_num_rows(MYSQL_STMT * stmt); +# 688 "mysql.h" +extern unsigned long int mysql_stmt_param_count(MYSQL_STMT * stmt); +# 705 "mysql.h" +extern MYSQL_RES * mysql_stmt_param_metadata(MYSQL_STMT * stmt); +# 680 "mysql.h" +extern int mysql_stmt_prepare(MYSQL_STMT * stmt, char const * query, unsigned long int); +# 698 "mysql.h" +extern my_bool mysql_stmt_reset(MYSQL_STMT * stmt); +# 704 "mysql.h" +extern MYSQL_RES * mysql_stmt_result_metadata(MYSQL_STMT * stmt); +# 709 "mysql.h" +extern MYSQL_ROW_OFFSET mysql_stmt_row_seek(MYSQL_STMT * stmt, MYSQL_ROW_OFFSET); +# 711 "mysql.h" +extern MYSQL_ROW_OFFSET mysql_stmt_row_tell(MYSQL_STMT * stmt); +# 700 "mysql.h" +extern my_bool mysql_stmt_send_long_data(MYSQL_STMT * stmt, unsigned int, char const * data, unsigned long int); +# 708 "mysql.h" +extern char const * mysql_stmt_sqlstate(MYSQL_STMT * stmt); +# 687 "mysql.h" +extern int mysql_stmt_store_result(MYSQL_STMT * stmt); +# 423 "mysql.h" +extern MYSQL_RES * mysql_store_result(MYSQL * mysql); +# 376 "mysql.h" +extern void mysql_thread_end(void); +# 400 "mysql.h" +extern unsigned long int mysql_thread_id(MYSQL * mysql); +# 375 "mysql.h" +extern my_bool mysql_thread_init(void); +# 540 "mysql.h" +extern unsigned int mysql_thread_safe(void); +# 76 "mysql.h" +extern char * mysql_unix_port; +# 424 "mysql.h" +extern MYSQL_RES * mysql_use_result(MYSQL * mysql); +# 398 "mysql.h" +extern unsigned int mysql_warning_count(MYSQL * mysql); +# 284 "mysql_com.h" +extern void net_clear(NET * net); +# 283 "mysql_com.h" +extern void net_end(NET * net); +# 286 "mysql_com.h" +extern my_bool net_flush(NET * net); +# 291 "mysql_com.h" +extern int net_real_write(NET * net, char const * packet, unsigned long int); +# 285 "mysql_com.h" +extern my_bool net_realloc(NET * net, unsigned long int); +# 751 "mysql.h" +extern unsigned long int net_safe_read(MYSQL * mysql); +# 288 "mysql_com.h" +extern my_bool net_write_command(NET * net, unsigned char, char const * header, unsigned long int, char const * packet, unsigned long int); +# 350 "mysql_com.h" +extern void randominit(struct rand_struct *, unsigned long int, unsigned long int); +# 364 "mysql_com.h" +extern void scramble(char * to, char const * message, char const * password); +# 357 "mysql_com.h" +extern void scramble_323(char * to, char const * message, char const * password); +# 32 "typelib.h" +extern TYPELIB sql_protocol_typelib; diff --git a/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c index db09a931c29..f24f1744363 100644 --- a/innobase/buf/buf0buf.c +++ b/innobase/buf/buf0buf.c @@ -221,6 +221,9 @@ in the free list to the frames. 5) When we have AWE enabled, we disable adaptive hash indexes. */ +/* Value in microseconds */ +static const int WAIT_FOR_READ = 20000; + buf_pool_t* buf_pool = NULL; /* The buffer buf_pool of the database */ #ifdef UNIV_DEBUG @@ -488,6 +491,9 @@ buf_block_init( block->n_pointers = 0; + mutex_create(&block->mutex); + mutex_set_level(&block->mutex, SYNC_BUF_BLOCK); + rw_lock_create(&(block->lock)); ut_ad(rw_lock_validate(&(block->lock))); @@ -756,8 +762,15 @@ buf_awe_map_page_to_frame( bck = UT_LIST_GET_LAST(buf_pool->awe_LRU_free_mapped); while (bck) { - if (bck->state == BUF_BLOCK_FILE_PAGE - && (bck->buf_fix_count != 0 || bck->io_fix != 0)) { + ibool skip; + + mutex_enter(&bck->mutex); + + skip = (bck->state == BUF_BLOCK_FILE_PAGE + && (bck->buf_fix_count != 0 || bck->io_fix != 0)); + + if (skip) { + mutex_exit(&bck->mutex); /* We have to skip this */ bck = UT_LIST_GET_PREV(awe_LRU_free_mapped, bck); @@ -790,6 +803,8 @@ buf_awe_map_page_to_frame( buf_pool->n_pages_awe_remapped++; + mutex_exit(&bck->mutex); + return; } } @@ -828,13 +843,22 @@ buf_block_make_young( /*=================*/ buf_block_t* block) /* in: block to make younger */ { +#ifdef UNIV_SYNC_DEBUG + ut_ad(!mutex_own(&(buf_pool->mutex))); +#endif /* UNIV_SYNC_DEBUG */ + + /* Note that we read freed_page_clock's without holding any mutex: + this is allowed since the result is used only in heuristics */ + if (buf_pool->freed_page_clock >= block->freed_page_clock - + 1 + (buf_pool->curr_size / 1024)) { + + 1 + (buf_pool->curr_size / 4)) { + mutex_enter(&buf_pool->mutex); /* There has been freeing activity in the LRU list: best to move to the head of the LRU list */ buf_LRU_make_block_young(block); + mutex_exit(&buf_pool->mutex); } } @@ -869,12 +893,16 @@ buf_block_free( /*===========*/ buf_block_t* block) /* in, own: block to be freed */ { - ut_a(block->state != BUF_BLOCK_FILE_PAGE); - mutex_enter(&(buf_pool->mutex)); + mutex_enter(&block->mutex); + + ut_a(block->state != BUF_BLOCK_FILE_PAGE); + buf_LRU_block_free_non_file_page(block); + mutex_exit(&block->mutex); + mutex_exit(&(buf_pool->mutex)); } @@ -1093,9 +1121,8 @@ buf_page_get_gen( #endif buf_pool->n_page_gets++; loop: - mutex_enter_fast(&(buf_pool->mutex)); - block = NULL; + mutex_enter_fast(&(buf_pool->mutex)); if (guess) { block = buf_block_align(guess); @@ -1133,6 +1160,8 @@ loop: goto loop; } + mutex_enter(&block->mutex); + ut_a(block->state == BUF_BLOCK_FILE_PAGE); must_read = FALSE; @@ -1142,9 +1171,9 @@ loop: must_read = TRUE; if (mode == BUF_GET_IF_IN_POOL) { - /* The page is only being read to buffer */ - mutex_exit(&(buf_pool->mutex)); + mutex_exit(&buf_pool->mutex); + mutex_exit(&block->mutex); return(NULL); } @@ -1168,7 +1197,7 @@ loop: #else buf_block_buf_fix_inc(block); #endif - buf_block_make_young(block); + mutex_exit(&buf_pool->mutex); /* Check if this is the first access to the page */ @@ -1176,10 +1205,13 @@ loop: block->accessed = TRUE; + mutex_exit(&block->mutex); + + buf_block_make_young(block); + #ifdef UNIV_DEBUG_FILE_ACCESSES ut_a(block->file_page_was_freed == FALSE); #endif - mutex_exit(&(buf_pool->mutex)); #ifdef UNIV_DEBUG buf_dbg_counter++; @@ -1204,13 +1236,14 @@ loop: } if (!success) { - mutex_enter(&(buf_pool->mutex)); + mutex_enter(&block->mutex); block->buf_fix_count--; + + mutex_exit(&block->mutex); #ifdef UNIV_SYNC_DEBUG rw_lock_s_unlock(&(block->debug_latch)); #endif - mutex_exit(&(buf_pool->mutex)); return(NULL); } @@ -1221,18 +1254,16 @@ loop: completes */ for (;;) { - mutex_enter(&(buf_pool->mutex)); + mutex_enter(&block->mutex); if (block->io_fix == BUF_IO_READ) { - mutex_exit(&(buf_pool->mutex)); + mutex_exit(&block->mutex); - /* Sleep 20 milliseconds */ - - os_thread_sleep(20000); + os_thread_sleep(WAIT_FOR_READ); } else { - mutex_exit(&(buf_pool->mutex)); + mutex_exit(&block->mutex); break; } @@ -1290,15 +1321,15 @@ buf_page_optimistic_get_func( ut_ad(mtr && block); ut_ad((rw_latch == RW_S_LATCH) || (rw_latch == RW_X_LATCH)); - - mutex_enter(&(buf_pool->mutex)); /* If AWE is used, block may have a different frame now, e.g., NULL */ - + + mutex_enter(&block->mutex); + if (UNIV_UNLIKELY(block->state != BUF_BLOCK_FILE_PAGE) - || UNIV_UNLIKELY(block->frame != guess)) { - exit_func: - mutex_exit(&(buf_pool->mutex)); + || UNIV_UNLIKELY(block->frame != guess)) { + + mutex_exit(&block->mutex); return(FALSE); } @@ -1308,15 +1339,14 @@ buf_page_optimistic_get_func( #else buf_block_buf_fix_inc(block); #endif - buf_block_make_young(block); - - /* Check if this is the first access to the page */ - accessed = block->accessed; - block->accessed = TRUE; - mutex_exit(&(buf_pool->mutex)); + mutex_exit(&block->mutex); + + buf_block_make_young(block); + + /* Check if this is the first access to the page */ ut_ad(!ibuf_inside() || ibuf_page(block->space, block->offset)); @@ -1331,13 +1361,16 @@ buf_page_optimistic_get_func( } if (UNIV_UNLIKELY(!success)) { - mutex_enter(&(buf_pool->mutex)); + mutex_enter(&block->mutex); block->buf_fix_count--; + + mutex_exit(&block->mutex); + #ifdef UNIV_SYNC_DEBUG rw_lock_s_unlock(&(block->debug_latch)); #endif - goto exit_func; + return(FALSE); } if (UNIV_UNLIKELY(!UT_DULINT_EQ(modify_clock, block->modify_clock))) { @@ -1350,13 +1383,16 @@ buf_page_optimistic_get_func( rw_lock_x_unlock(&(block->lock)); } - mutex_enter(&(buf_pool->mutex)); + mutex_enter(&block->mutex); block->buf_fix_count--; + + mutex_exit(&block->mutex); + #ifdef UNIV_SYNC_DEBUG rw_lock_s_unlock(&(block->debug_latch)); #endif - goto exit_func; + return(FALSE); } mtr_memo_push(mtr, block, fix_type); @@ -1413,10 +1449,10 @@ buf_page_get_known_nowait( ut_ad(mtr); ut_ad((rw_latch == RW_S_LATCH) || (rw_latch == RW_X_LATCH)); - mutex_enter(&(buf_pool->mutex)); - block = buf_block_align(guess); + mutex_enter(&block->mutex); + if (block->state == BUF_BLOCK_REMOVE_HASH) { /* Another thread is just freeing the block from the LRU list of the buffer pool: do not try to access this page; this @@ -1425,7 +1461,7 @@ buf_page_get_known_nowait( we have already removed it from the page address hash table of the buffer pool. */ - mutex_exit(&(buf_pool->mutex)); + mutex_exit(&block->mutex); return(FALSE); } @@ -1437,12 +1473,12 @@ buf_page_get_known_nowait( #else buf_block_buf_fix_inc(block); #endif + mutex_exit(&block->mutex); + if (mode == BUF_MAKE_YOUNG) { buf_block_make_young(block); } - mutex_exit(&(buf_pool->mutex)); - ut_ad(!ibuf_inside() || (mode == BUF_KEEP_OLD)); if (rw_latch == RW_S_LATCH) { @@ -1456,13 +1492,15 @@ buf_page_get_known_nowait( } if (!success) { - mutex_enter(&(buf_pool->mutex)); + mutex_enter(&block->mutex); block->buf_fix_count--; + + mutex_exit(&block->mutex); + #ifdef UNIV_SYNC_DEBUG rw_lock_s_unlock(&(block->debug_latch)); #endif - mutex_exit(&(buf_pool->mutex)); return(FALSE); } @@ -1510,8 +1548,7 @@ buf_page_init_for_backup_restore( block->offset = offset; block->lock_hash_val = 0; - block->lock_mutex = NULL; - + block->freed_page_clock = 0; block->newest_modification = ut_dulint_zero; @@ -1543,6 +1580,7 @@ buf_page_init( { #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex))); + ut_ad(mutex_own(&(block->mutex))); #endif /* UNIV_SYNC_DEBUG */ ut_a(block->state != BUF_BLOCK_FILE_PAGE); @@ -1557,8 +1595,7 @@ buf_page_init( block->index = NULL; block->lock_hash_val = lock_rec_hash(space, offset); - block->lock_mutex = NULL; - + /* Insert into the hash table of file pages */ if (buf_page_hash_get(space, offset)) { @@ -1650,6 +1687,7 @@ buf_page_init_for_read( ut_a(block); mutex_enter(&(buf_pool->mutex)); + mutex_enter(&block->mutex); if (fil_tablespace_deleted_or_being_deleted_in_mem(space, tablespace_version)) { @@ -1662,7 +1700,9 @@ buf_page_init_for_read( /* The page belongs to a space which has been deleted or is being deleted, or the page is already in buf_pool, return */ + mutex_exit(&block->mutex); mutex_exit(&(buf_pool->mutex)); + buf_block_free(block); if (mode == BUF_READ_IBUF_PAGES_ONLY) { @@ -1682,6 +1722,7 @@ buf_page_init_for_read( buf_LRU_add_block(block, TRUE); /* TRUE == to old blocks */ block->io_fix = BUF_IO_READ; + buf_pool->n_pend_reads++; /* We set a pass-type x-lock on the frame because then the same @@ -1693,6 +1734,7 @@ buf_page_init_for_read( rw_lock_x_lock_gen(&(block->lock), BUF_IO_READ); + mutex_exit(&block->mutex); mutex_exit(&(buf_pool->mutex)); if (mode == BUF_READ_IBUF_PAGES_ONLY) { @@ -1757,6 +1799,8 @@ buf_page_create( block = free_block; + mutex_enter(&block->mutex); + buf_page_init(space, offset, block); /* The block must be put to the LRU list */ @@ -1767,13 +1811,15 @@ buf_page_create( #else buf_block_buf_fix_inc(block); #endif + buf_pool->n_pages_created++; + + mutex_exit(&(buf_pool->mutex)); + mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX); block->accessed = TRUE; - buf_pool->n_pages_created++; - - mutex_exit(&(buf_pool->mutex)); + mutex_exit(&block->mutex); /* Delete possible entries for the page from the insert buffer: such can exist if the page belonged to an index which was dropped */ @@ -1822,6 +1868,12 @@ buf_page_io_complete( ut_a(block->state == BUF_BLOCK_FILE_PAGE); + /* We do not need protect block->io_fix here by block->mutex to read + it because this is the only function where we can change the value + from BUF_IO_READ or BUF_IO_WRITE to some other value, and our code + ensures that this is the only thread that handles the i/o for this + block. */ + io_type = block->io_fix; if (io_type == BUF_IO_READ) { @@ -1890,11 +1942,12 @@ buf_page_io_complete( } } + mutex_enter(&(buf_pool->mutex)); + mutex_enter(&block->mutex); + #ifdef UNIV_IBUF_DEBUG ut_a(ibuf_count_get(block->space, block->offset) == 0); #endif - mutex_enter(&(buf_pool->mutex)); - /* Because this thread which does the unlocking is not the same that did the locking, we use a pass value != 0 in unlock, which simply removes the newest lock debug record, without checking the thread @@ -1937,6 +1990,7 @@ buf_page_io_complete( #endif /* UNIV_DEBUG */ } + mutex_exit(&block->mutex); mutex_exit(&(buf_pool->mutex)); #ifdef UNIV_DEBUG @@ -1999,6 +2053,8 @@ buf_validate(void) block = buf_pool_get_nth_block(buf_pool, i); + mutex_enter(&block->mutex); + if (block->state == BUF_BLOCK_FILE_PAGE) { ut_a(buf_page_hash_get(block->space, @@ -2042,6 +2098,8 @@ buf_validate(void) } else if (block->state == BUF_BLOCK_NOT_USED) { n_free++; } + + mutex_exit(&block->mutex); } if (n_lru + n_free > buf_pool->curr_size) { @@ -2185,11 +2243,17 @@ buf_get_latched_pages_number(void) for (i = 0; i < buf_pool->curr_size; i++) { - block = buf_pool_get_nth_block(buf_pool, i); + block = buf_pool_get_nth_block(buf_pool, i); + + if (block->magic_n == BUF_BLOCK_MAGIC_N) { + mutex_enter(&block->mutex); - if (((block->buf_fix_count != 0) || (block->io_fix != 0)) && - block->magic_n == BUF_BLOCK_MAGIC_N ) - fixed_pages_number++; + if (block->buf_fix_count != 0 || block->io_fix != 0) { + fixed_pages_number++; + } + + mutex_exit(&block->mutex); + } } mutex_exit(&(buf_pool->mutex)); @@ -2354,16 +2418,21 @@ buf_all_freed(void) block = buf_pool_get_nth_block(buf_pool, i); + mutex_enter(&block->mutex); + if (block->state == BUF_BLOCK_FILE_PAGE) { if (!buf_flush_ready_for_replace(block)) { fprintf(stderr, "Page %lu %lu still fixed or dirty\n", - (ulong) block->space, (ulong) block->offset); + (ulong) block->space, + (ulong) block->offset); ut_error; } } + + mutex_exit(&block->mutex); } mutex_exit(&(buf_pool->mutex)); diff --git a/innobase/buf/buf0flu.c b/innobase/buf/buf0flu.c index e39d1ae0a71..fc7b60bf5fb 100644 --- a/innobase/buf/buf0flu.c +++ b/innobase/buf/buf0flu.c @@ -114,6 +114,7 @@ buf_flush_ready_for_replace( { #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex))); + ut_ad(mutex_own(&block->mutex)); #endif /* UNIV_SYNC_DEBUG */ if (block->state != BUF_BLOCK_FILE_PAGE) { ut_print_timestamp(stderr); @@ -148,6 +149,7 @@ buf_flush_ready_for_flush( { #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex))); + ut_ad(mutex_own(&(block->mutex))); #endif /* UNIV_SYNC_DEBUG */ ut_a(block->state == BUF_BLOCK_FILE_PAGE); @@ -539,8 +541,15 @@ buf_flush_try_page( ut_a(!block || block->state == BUF_BLOCK_FILE_PAGE); + if (!block) { + mutex_exit(&(buf_pool->mutex)); + return(0); + } + + mutex_enter(&block->mutex); + if (flush_type == BUF_FLUSH_LIST - && block && buf_flush_ready_for_flush(block, flush_type)) { + && buf_flush_ready_for_flush(block, flush_type)) { block->io_fix = BUF_IO_WRITE; @@ -578,6 +587,7 @@ buf_flush_try_page( locked = TRUE; } + mutex_exit(&block->mutex); mutex_exit(&(buf_pool->mutex)); if (!locked) { @@ -598,8 +608,8 @@ buf_flush_try_page( return(1); - } else if (flush_type == BUF_FLUSH_LRU && block - && buf_flush_ready_for_flush(block, flush_type)) { + } else if (flush_type == BUF_FLUSH_LRU + && buf_flush_ready_for_flush(block, flush_type)) { /* VERY IMPORTANT: Because any thread may call the LRU flush, even when owning @@ -639,14 +649,15 @@ buf_flush_try_page( buf_pool mutex: this ensures that the latch is acquired immediately. */ + mutex_exit(&block->mutex); mutex_exit(&(buf_pool->mutex)); buf_flush_write_block_low(block); return(1); - } else if (flush_type == BUF_FLUSH_SINGLE_PAGE && block - && buf_flush_ready_for_flush(block, flush_type)) { + } else if (flush_type == BUF_FLUSH_SINGLE_PAGE + && buf_flush_ready_for_flush(block, flush_type)) { block->io_fix = BUF_IO_WRITE; @@ -672,6 +683,7 @@ buf_flush_try_page( (buf_pool->n_flush[flush_type])++; + mutex_exit(&block->mutex); mutex_exit(&(buf_pool->mutex)); rw_lock_s_lock_gen(&(block->lock), BUF_IO_WRITE); @@ -688,11 +700,12 @@ buf_flush_try_page( buf_flush_write_block_low(block); return(1); - } else { - mutex_exit(&(buf_pool->mutex)); + } - return(0); - } + mutex_exit(&block->mutex); + mutex_exit(&(buf_pool->mutex)); + + return(0); } /*************************************************************** @@ -737,34 +750,48 @@ buf_flush_try_neighbors( block = buf_page_hash_get(space, i); ut_a(!block || block->state == BUF_BLOCK_FILE_PAGE); - if (block && flush_type == BUF_FLUSH_LRU && i != offset - && !block->old) { + if (!block) { + + continue; + + } else if (flush_type == BUF_FLUSH_LRU && i != offset + && !block->old) { /* We avoid flushing 'non-old' blocks in an LRU flush, because the flushed blocks are soon freed */ continue; - } + } else { + + mutex_enter(&block->mutex); + + if (buf_flush_ready_for_flush(block, flush_type) + && (i == offset || block->buf_fix_count == 0)) { + /* We only try to flush those + neighbors != offset where the buf fix count is + zero, as we then know that we probably can + latch the page without a semaphore wait. + Semaphore waits are expensive because we must + flush the doublewrite buffer before we start + waiting. */ - if (block && buf_flush_ready_for_flush(block, flush_type) - && (i == offset || block->buf_fix_count == 0)) { - /* We only try to flush those neighbors != offset - where the buf fix count is zero, as we then know that - we probably can latch the page without a semaphore - wait. Semaphore waits are expensive because we must - flush the doublewrite buffer before we start - waiting. */ + mutex_exit(&block->mutex); - mutex_exit(&(buf_pool->mutex)); + mutex_exit(&(buf_pool->mutex)); - /* Note: as we release the buf_pool mutex above, in - buf_flush_try_page we cannot be sure the page is still - in a flushable state: therefore we check it again - inside that function. */ + /* Note: as we release the buf_pool mutex + above, in buf_flush_try_page we cannot be sure + the page is still in a flushable state: + therefore we check it again inside that + function. */ - count += buf_flush_try_page(space, i, flush_type); + count += buf_flush_try_page(space, i, + flush_type); - mutex_enter(&(buf_pool->mutex)); + mutex_enter(&(buf_pool->mutex)); + } else { + mutex_exit(&block->mutex); + } } } @@ -858,12 +885,15 @@ buf_flush_batch( while ((block != NULL) && !found) { ut_a(block->state == BUF_BLOCK_FILE_PAGE); + mutex_enter(&block->mutex); + if (buf_flush_ready_for_flush(block, flush_type)) { found = TRUE; space = block->space; offset = block->offset; + mutex_exit(&block->mutex); mutex_exit(&(buf_pool->mutex)); old_page_count = page_count; @@ -881,10 +911,14 @@ buf_flush_batch( } else if (flush_type == BUF_FLUSH_LRU) { + mutex_exit(&block->mutex); + block = UT_LIST_GET_PREV(LRU, block); } else { ut_ad(flush_type == BUF_FLUSH_LIST); + mutex_exit(&block->mutex); + block = UT_LIST_GET_PREV(flush_list, block); } } @@ -966,10 +1000,14 @@ buf_flush_LRU_recommendation(void) + BUF_FLUSH_EXTRA_MARGIN) && (distance < BUF_LRU_FREE_SEARCH_LEN)) { + mutex_enter(&block->mutex); + if (buf_flush_ready_for_replace(block)) { n_replaceable++; } + mutex_exit(&block->mutex); + distance++; block = UT_LIST_GET_PREV(LRU, block); diff --git a/innobase/buf/buf0lru.c b/innobase/buf/buf0lru.c index 8b135cc5db3..dfee2add045 100644 --- a/innobase/buf/buf0lru.c +++ b/innobase/buf/buf0lru.c @@ -86,6 +86,9 @@ scan_again: block = UT_LIST_GET_LAST(buf_pool->LRU); while (block != NULL) { + + mutex_enter(&block->mutex); + ut_a(block->state == BUF_BLOCK_FILE_PAGE); if (block->space == id @@ -112,6 +115,8 @@ scan_again: if (block->is_hashed) { page_no = block->offset; + mutex_exit(&block->mutex); + mutex_exit(&(buf_pool->mutex)); /* Note that the following call will acquire @@ -138,6 +143,7 @@ scan_again: buf_LRU_block_free_hashed_page(block); } next_page: + mutex_exit(&block->mutex); block = UT_LIST_GET_PREV(LRU, block); } @@ -211,6 +217,9 @@ buf_LRU_search_and_free_block( while (block != NULL) { ut_a(block->in_LRU_list); + + mutex_enter(&block->mutex); + if (buf_flush_ready_for_replace(block)) { #ifdef UNIV_DEBUG @@ -225,6 +234,7 @@ buf_LRU_search_and_free_block( buf_LRU_block_remove_hashed_page(block); mutex_exit(&(buf_pool->mutex)); + mutex_exit(&block->mutex); /* Remove possible adaptive hash index built on the page; in the case of AWE the block may not have a @@ -233,15 +243,21 @@ buf_LRU_search_and_free_block( if (block->frame) { btr_search_drop_page_hash_index(block->frame); } - mutex_enter(&(buf_pool->mutex)); ut_a(block->buf_fix_count == 0); + mutex_enter(&(buf_pool->mutex)); + mutex_enter(&block->mutex); + buf_LRU_block_free_hashed_page(block); freed = TRUE; + mutex_exit(&block->mutex); break; } + + mutex_exit(&block->mutex); + block = UT_LIST_GET_PREV(LRU, block); distance++; @@ -415,8 +431,12 @@ loop: } } + mutex_enter(&block->mutex); + block->state = BUF_BLOCK_READY_FOR_USE; + mutex_exit(&block->mutex); + mutex_exit(&(buf_pool->mutex)); if (started_monitor) { @@ -818,6 +838,7 @@ buf_LRU_block_free_non_file_page( { #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex))); + ut_ad(mutex_own(&block->mutex)); #endif /* UNIV_SYNC_DEBUG */ ut_ad(block); @@ -857,6 +878,7 @@ buf_LRU_block_remove_hashed_page( { #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex))); + ut_ad(mutex_own(&block->mutex)); #endif /* UNIV_SYNC_DEBUG */ ut_ad(block); @@ -914,6 +936,7 @@ buf_LRU_block_free_hashed_page( { #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex))); + ut_ad(mutex_own(&block->mutex)); #endif /* UNIV_SYNC_DEBUG */ ut_a(block->state == BUF_BLOCK_REMOVE_HASH); diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c index c7d6ffd2c22..e20d8b6e83a 100644 --- a/innobase/dict/dict0crea.c +++ b/innobase/dict/dict0crea.c @@ -724,8 +724,10 @@ dict_truncate_index_tree( /* out: new root page number, or FIL_NULL on failure */ dict_table_t* table, /* in: the table the index belongs to */ - rec_t* rec, /* in: record in the clustered index of - SYS_INDEXES table */ + btr_pcur_t* pcur, /* in/out: persistent cursor pointing to + record in the clustered index of + SYS_INDEXES table. The cursor may be + repositioned in this call. */ mtr_t* mtr) /* in: mtr having the latch on the record page. The mtr may be committed and restarted in this call. */ @@ -734,6 +736,7 @@ dict_truncate_index_tree( ulint space; ulint type; dulint index_id; + rec_t* rec; byte* ptr; ulint len; ulint comp; @@ -744,6 +747,7 @@ dict_truncate_index_tree( #endif /* UNIV_SYNC_DEBUG */ ut_a(!dict_sys->sys_indexes->comp); + rec = btr_pcur_get_rec(pcur); ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len); ut_ad(len == 4); @@ -809,10 +813,11 @@ dict_truncate_index_tree( /* We will need to commit the mini-transaction in order to avoid deadlocks in the btr_create() call, because otherwise we would be freeing and allocating pages in the same mini-transaction. */ + btr_pcur_store_position(pcur, mtr); mtr_commit(mtr); - /* mtr_commit() will invalidate rec. */ - rec = NULL; + mtr_start(mtr); + btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur, mtr); /* Find the index corresponding to this SYS_INDEXES record. */ for (index = UT_LIST_GET_FIRST(table->indexes); diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c index 64987294654..65320b57183 100644 --- a/innobase/fil/fil0fil.c +++ b/innobase/fil/fil0fil.c @@ -4285,29 +4285,47 @@ fil_flush_file_spaces( { fil_system_t* system = fil_system; fil_space_t* space; + ulint* space_ids; + ulint n_space_ids; + ulint i; mutex_enter(&(system->mutex)); - space = UT_LIST_GET_FIRST(system->unflushed_spaces); + n_space_ids = UT_LIST_GET_LEN(system->unflushed_spaces); + if (n_space_ids == 0) { - while (space) { - if (space->purpose == purpose && !space->is_being_deleted) { + mutex_exit(&system->mutex); + return; + } - space->n_pending_flushes++; /* prevent dropping of the - space while we are - flushing */ - mutex_exit(&(system->mutex)); + /* Assemble a list of space ids to flush. Previously, we + traversed system->unflushed_spaces and called UT_LIST_GET_NEXT() + on a space that was just removed from the list by fil_flush(). + Thus, the space could be dropped and the memory overwritten. */ + space_ids = mem_alloc(n_space_ids * sizeof *space_ids); - fil_flush(space->id); + n_space_ids = 0; - mutex_enter(&(system->mutex)); + for (space = UT_LIST_GET_FIRST(system->unflushed_spaces); + space; + space = UT_LIST_GET_NEXT(unflushed_spaces, space)) { + + if (space->purpose == purpose && !space->is_being_deleted) { - space->n_pending_flushes--; + space_ids[n_space_ids++] = space->id; } - space = UT_LIST_GET_NEXT(unflushed_spaces, space); } - - mutex_exit(&(system->mutex)); + + mutex_exit(&system->mutex); + + /* Flush the spaces. It will not hurt to call fil_flush() on + a non-existing space id. */ + for (i = 0; i < n_space_ids; i++) { + + fil_flush(space_ids[i]); + } + + mem_free(space_ids); } /********************************************************************** diff --git a/innobase/include/buf0buf.h b/innobase/include/buf0buf.h index fc1d9a64c7f..11e5bb39e63 100644 --- a/innobase/include/buf0buf.h +++ b/innobase/include/buf0buf.h @@ -461,8 +461,8 @@ Gets the mutex number protecting the page record lock hash chain in the lock table. */ UNIV_INLINE mutex_t* -buf_frame_get_lock_mutex( -/*=====================*/ +buf_frame_get_mutex( +/*================*/ /* out: mutex */ byte* ptr); /* in: pointer to within a buffer frame */ /*********************************************************************** @@ -713,7 +713,10 @@ struct buf_block_struct{ ulint magic_n; /* magic number to check */ ulint state; /* state of the control block: - BUF_BLOCK_NOT_USED, ... */ + BUF_BLOCK_NOT_USED, ...; changing + this is only allowed when a thread + has BOTH the buffer pool mutex AND + block->mutex locked */ byte* frame; /* pointer to buffer frame which is of size UNIV_PAGE_SIZE, and aligned to an address divisible by @@ -731,8 +734,12 @@ struct buf_block_struct{ ulint offset; /* page number within the space */ ulint lock_hash_val; /* hashed value of the page address in the record lock hash table */ - mutex_t* lock_mutex; /* mutex protecting the chain in the - record lock hash table */ + mutex_t mutex; /* mutex protecting this block: + state (also protected by the buffer + pool mutex), io_fix, buf_fix_count, + and accessed; we introduce this new + mutex in InnoDB-5.1 to relieve + contention on the buffer pool mutex */ rw_lock_t lock; /* read-write lock of the buffer frame */ buf_block_t* hash; /* node used in chaining to the page @@ -788,20 +795,27 @@ struct buf_block_struct{ in heuristic algorithms, because of the possibility of a wrap-around! */ ulint freed_page_clock;/* the value of freed_page_clock - buffer pool when this block was - last time put to the head of the - LRU list */ + of the buffer pool when this block was + the last time put to the head of the + LRU list; a thread is allowed to + read this for heuristic purposes + without holding any mutex or latch */ ibool old; /* TRUE if the block is in the old blocks in the LRU list */ ibool accessed; /* TRUE if the page has been accessed while in the buffer pool: read-ahead may read in pages which have not been - accessed yet */ + accessed yet; this is protected by + block->mutex; a thread is allowed to + read this for heuristic purposes + without holding any mutex or latch */ ulint buf_fix_count; /* count of how manyfold this block - is currently bufferfixed */ + is currently bufferfixed; this is + protected by block->mutex */ ulint io_fix; /* if a read is pending to the frame, io_fix is BUF_IO_READ, in the case - of a write BUF_IO_WRITE, otherwise 0 */ + of a write BUF_IO_WRITE, otherwise 0; + this is protected by block->mutex */ /* 4. Optimistic search field */ dulint modify_clock; /* this clock is incremented every @@ -962,7 +976,9 @@ struct buf_pool_struct{ number of buffer blocks removed from the end of the LRU list; NOTE that this counter may wrap around at 4 - billion! */ + billion! A thread is allowed to + read this for heuristic purposes + without holding any mutex or latch */ ulint LRU_flush_ended;/* when an LRU flush ends for a page, this is incremented by one; this is set to zero when a buffer block is diff --git a/innobase/include/buf0buf.ic b/innobase/include/buf0buf.ic index af32db10b5f..ddc91b8d66c 100644 --- a/innobase/include/buf0buf.ic +++ b/innobase/include/buf0buf.ic @@ -330,8 +330,8 @@ Gets the mutex number protecting the page record lock hash chain in the lock table. */ UNIV_INLINE mutex_t* -buf_frame_get_lock_mutex( -/*=====================*/ +buf_frame_get_mutex( +/*================*/ /* out: mutex */ byte* ptr) /* in: pointer to within a buffer frame */ { @@ -339,7 +339,7 @@ buf_frame_get_lock_mutex( block = buf_block_align(ptr); - return(block->lock_mutex); + return(&block->mutex); } /************************************************************************* @@ -512,6 +512,7 @@ buf_block_buf_fix_inc_debug( ret = rw_lock_s_lock_func_nowait(&(block->debug_latch), file, line); ut_ad(ret == TRUE); + ut_ad(mutex_own(&block->mutex)); #endif block->buf_fix_count++; } @@ -524,6 +525,9 @@ buf_block_buf_fix_inc( /*==================*/ buf_block_t* block) /* in: block to bufferfix */ { +#ifdef UNIV_SYNC_DEBUG + ut_ad(mutex_own(&block->mutex)); +#endif block->buf_fix_count++; } #endif /* UNIV_SYNC_DEBUG */ @@ -618,23 +622,24 @@ buf_page_release( ut_ad(block); - mutex_enter_fast(&(buf_pool->mutex)); - ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_a(block->buf_fix_count > 0); if (rw_latch == RW_X_LATCH && mtr->modifications) { - + mutex_enter(&buf_pool->mutex); buf_flush_note_modification(block, mtr); + mutex_exit(&buf_pool->mutex); } + mutex_enter(&block->mutex); + #ifdef UNIV_SYNC_DEBUG rw_lock_s_unlock(&(block->debug_latch)); #endif buf_fix_count = block->buf_fix_count; block->buf_fix_count = buf_fix_count - 1; - mutex_exit(&(buf_pool->mutex)); + mutex_exit(&block->mutex); if (rw_latch == RW_S_LATCH) { rw_lock_s_unlock(&(block->lock)); diff --git a/innobase/include/dict0crea.h b/innobase/include/dict0crea.h index 5dd571be59c..44acca61c5e 100644 --- a/innobase/include/dict0crea.h +++ b/innobase/include/dict0crea.h @@ -62,8 +62,10 @@ dict_truncate_index_tree( /* out: new root page number, or FIL_NULL on failure */ dict_table_t* table, /* in: the table the index belongs to */ - rec_t* rec, /* in: record in the clustered index of - SYS_INDEXES table */ + btr_pcur_t* pcur, /* in/out: persistent cursor pointing to + record in the clustered index of + SYS_INDEXES table. The cursor may be + repositioned in this call. */ mtr_t* mtr); /* in: mtr having the latch on the record page. The mtr may be committed and restarted in this call. */ diff --git a/innobase/include/sync0arr.h b/innobase/include/sync0arr.h index fecd910683e..ba712d14aad 100644 --- a/innobase/include/sync0arr.h +++ b/innobase/include/sync0arr.h @@ -75,17 +75,12 @@ sync_array_free_cell( sync_array_t* arr, /* in: wait array */ ulint index); /* in: index of the cell in array */ /************************************************************************** -Looks for the cells in the wait array which refer -to the wait object specified, -and sets their corresponding events to the signaled state. In this -way releases the threads waiting for the object to contend for the object. -It is possible that no such cell is found, in which case does nothing. */ +Note that one of the wait objects was signalled. */ void -sync_array_signal_object( -/*=====================*/ - sync_array_t* arr, /* in: wait array */ - void* object);/* in: wait object */ +sync_array_object_signalled( +/*========================*/ + sync_array_t* arr); /* in: wait array */ /************************************************************************** If the wakeup algorithm does not work perfectly at semaphore relases, this function will do the waking (see the comment in mutex_exit). This diff --git a/innobase/include/sync0rw.h b/innobase/include/sync0rw.h index 911c8ac3f4a..741f9500612 100644 --- a/innobase/include/sync0rw.h +++ b/innobase/include/sync0rw.h @@ -411,6 +411,7 @@ blocked by readers, a writer may queue for the lock by setting the writer field. Then no new readers are allowed in. */ struct rw_lock_struct { + os_event_t event; /* Used by sync0arr.c for thread queueing */ ulint reader_count; /* Number of readers who have locked this lock in the shared mode */ ulint writer; /* This field is set to RW_LOCK_EX if there diff --git a/innobase/include/sync0rw.ic b/innobase/include/sync0rw.ic index 9e15475ae53..31a1ea6562a 100644 --- a/innobase/include/sync0rw.ic +++ b/innobase/include/sync0rw.ic @@ -382,7 +382,8 @@ rw_lock_s_unlock_func( mutex_exit(mutex); if (UNIV_UNLIKELY(sg)) { - sync_array_signal_object(sync_primary_wait_array, lock); + os_event_set(lock->event); + sync_array_object_signalled(sync_primary_wait_array); } ut_ad(rw_lock_validate(lock)); @@ -462,7 +463,8 @@ rw_lock_x_unlock_func( mutex_exit(&(lock->mutex)); if (UNIV_UNLIKELY(sg)) { - sync_array_signal_object(sync_primary_wait_array, lock); + os_event_set(lock->event); + sync_array_object_signalled(sync_primary_wait_array); } ut_ad(rw_lock_validate(lock)); diff --git a/innobase/include/sync0sync.h b/innobase/include/sync0sync.h index 5955ab9a06a..9893921c5d2 100644 --- a/innobase/include/sync0sync.h +++ b/innobase/include/sync0sync.h @@ -453,6 +453,7 @@ Do not use its fields directly! The structure used in the spin lock implementation of a mutual exclusion semaphore. */ struct mutex_struct { + os_event_t event; /* Used by sync0arr.c for the wait queue */ ulint lock_word; /* This ulint is the target of the atomic test-and-set instruction in Win32 */ #if !defined(_WIN32) || !defined(UNIV_CAN_USE_X86_ASSEMBLER) diff --git a/innobase/os/os0sync.c b/innobase/os/os0sync.c index 8bafb73baf8..a3204a7b3e8 100644 --- a/innobase/os/os0sync.c +++ b/innobase/os/os0sync.c @@ -21,6 +21,7 @@ Created 9/6/1995 Heikki Tuuri /* Type definition for an operating system mutex struct */ struct os_mutex_struct{ + os_event_t event; /* Used by sync0arr.c for queing threads */ void* handle; /* OS handle to mutex */ ulint count; /* we use this counter to check that the same thread does not @@ -35,6 +36,7 @@ struct os_mutex_struct{ /* Mutex protecting counts and the lists of OS mutexes and events */ os_mutex_t os_sync_mutex; ibool os_sync_mutex_inited = FALSE; +ibool os_sync_free_called = FALSE; /* This is incremented by 1 in os_thread_create and decremented by 1 in os_thread_exit */ @@ -50,6 +52,10 @@ ulint os_event_count = 0; ulint os_mutex_count = 0; ulint os_fast_mutex_count = 0; +/* Because a mutex is embedded inside an event and there is an +event embedded inside a mutex, on free, this generates a recursive call. +This version of the free event function doesn't acquire the global lock */ +static void os_event_free_internal(os_event_t event); /************************************************************* Initializes global event and OS 'slow' mutex lists. */ @@ -76,6 +82,7 @@ os_sync_free(void) os_event_t event; os_mutex_t mutex; + os_sync_free_called = TRUE; event = UT_LIST_GET_FIRST(os_event_list); while (event) { @@ -99,6 +106,7 @@ os_sync_free(void) mutex = UT_LIST_GET_FIRST(os_mutex_list); } + os_sync_free_called = FALSE; } /************************************************************* @@ -146,14 +154,21 @@ os_event_create( event->signal_count = 0; #endif /* __WIN__ */ - /* Put to the list of events */ - os_mutex_enter(os_sync_mutex); + /* The os_sync_mutex can be NULL because during startup an event + can be created [ because it's embedded in the mutex/rwlock ] before + this module has been initialized */ + if (os_sync_mutex != NULL) { + os_mutex_enter(os_sync_mutex); + } + /* Put to the list of events */ UT_LIST_ADD_FIRST(os_event_list, os_event_list, event); os_event_count++; - os_mutex_exit(os_sync_mutex); + if (os_sync_mutex != NULL) { + os_mutex_exit(os_sync_mutex); + } return(event); } @@ -256,6 +271,35 @@ os_event_reset( } /************************************************************** +Frees an event object, without acquiring the global lock. */ +static +void +os_event_free_internal( +/*===================*/ + os_event_t event) /* in: event to free */ +{ +#ifdef __WIN__ + ut_a(event); + + ut_a(CloseHandle(event->handle)); +#else + ut_a(event); + + /* This is to avoid freeing the mutex twice */ + os_fast_mutex_free(&(event->os_mutex)); + + ut_a(0 == pthread_cond_destroy(&(event->cond_var))); +#endif + /* Remove from the list of events */ + + UT_LIST_REMOVE(os_event_list, os_event_list, event); + + os_event_count--; + + ut_free(event); +} + +/************************************************************** Frees an event object. */ void @@ -456,6 +500,7 @@ os_mutex_create( mutex_str->handle = mutex; mutex_str->count = 0; + mutex_str->event = os_event_create(NULL); if (os_sync_mutex_inited) { /* When creating os_sync_mutex itself we cannot reserve it */ @@ -532,6 +577,10 @@ os_mutex_free( { ut_a(mutex); + if (!os_sync_free_called) { + os_event_free_internal(mutex->event); + } + if (os_sync_mutex_inited) { os_mutex_enter(os_sync_mutex); } diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 955c7139de7..efbb93ba9f5 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -2920,12 +2920,10 @@ do not allow the TRUNCATE. We also reserve the data dictionary latch. */ goto next_rec; } - btr_pcur_store_position(&pcur, &mtr); + /* This call may commit and restart mtr + and reposition pcur. */ + root_page_no = dict_truncate_index_tree(table, &pcur, &mtr); - /* This call may commit and restart mtr. */ - root_page_no = dict_truncate_index_tree(table, rec, &mtr); - - btr_pcur_restore_position(BTR_MODIFY_LEAF, &pcur, &mtr); rec = btr_pcur_get_rec(&pcur); if (root_page_no != FIL_NULL) { diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index ec56afbb4f5..f8a65e6ff82 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -1323,6 +1323,12 @@ rec_loop: ULINT_UNDEFINED, &heap); if (srv_locks_unsafe_for_binlog) { + + if (page_rec_is_supremum(rec)) { + + goto next_rec; + } + lock_type = LOCK_REC_NOT_GAP; } else { lock_type = LOCK_ORDINARY; diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 8530f117c9d..b41dcbe44cd 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -1142,10 +1142,7 @@ innobase_start_or_create_for_mysql(void) #if defined(__NETWARE__) -/* Create less event semaphores because Win 98/ME had difficulty creating -40000 event semaphores. -Comment from Novell, Inc.: also, these just take a lot of memory on -NetWare. */ + /* Comment from Novell, Inc.: These take a lot of memory on NetWare.*/ srv_max_n_threads = 1000; #else if (srv_pool_size >= 1000 * 1024) { diff --git a/innobase/sync/sync0arr.c b/innobase/sync/sync0arr.c index 198ef49ca9f..64f9310bad3 100644 --- a/innobase/sync/sync0arr.c +++ b/innobase/sync/sync0arr.c @@ -62,9 +62,6 @@ struct sync_cell_struct { ibool waiting; /* TRUE if the thread has already called sync_array_event_wait on this cell */ - ibool event_set; /* TRUE if the event is set */ - os_event_t event; /* operating system event - semaphore handle */ time_t reservation_time;/* time when the thread reserved the wait cell */ }; @@ -218,10 +215,7 @@ sync_array_create( for (i = 0; i < n_cells; i++) { cell = sync_array_get_nth_cell(arr, i); cell->wait_object = NULL; - - /* Create an operating system event semaphore with no name */ - cell->event = os_event_create(NULL); - cell->event_set = FALSE; /* it is created in reset state */ + cell->waiting = FALSE; } return(arr); @@ -235,19 +229,12 @@ sync_array_free( /*============*/ sync_array_t* arr) /* in, own: sync wait array */ { - ulint i; - sync_cell_t* cell; ulint protection; ut_a(arr->n_reserved == 0); sync_array_validate(arr); - for (i = 0; i < arr->n_cells; i++) { - cell = sync_array_get_nth_cell(arr, i); - os_event_free(cell->event); - } - protection = arr->protection; /* Release the mutex protecting the wait array complex */ @@ -293,27 +280,19 @@ sync_array_validate( } /*********************************************************************** -Puts the cell event in set state. */ -static -void -sync_cell_event_set( -/*================*/ - sync_cell_t* cell) /* in: array cell */ -{ - os_event_set(cell->event); - cell->event_set = TRUE; -} - -/*********************************************************************** Puts the cell event in reset state. */ static void sync_cell_event_reset( /*==================*/ - sync_cell_t* cell) /* in: array cell */ + ulint type, /* in: lock type mutex/rw_lock */ + void* object) /* in: the rw_lock/mutex object */ { - os_event_reset(cell->event); - cell->event_set = FALSE; + if (type == SYNC_MUTEX) { + os_event_reset(((mutex_t *) object)->event); + } else { + os_event_reset(((rw_lock_t *) object)->event); + } } /********************************************************************** @@ -346,14 +325,7 @@ sync_array_reserve_cell( if (cell->wait_object == NULL) { - /* Make sure the event is reset */ - if (cell->event_set) { - sync_cell_event_reset(cell); - } - - cell->reservation_time = time(NULL); - cell->thread = os_thread_get_curr_id(); - + cell->waiting = FALSE; cell->wait_object = object; if (type == SYNC_MUTEX) { @@ -363,7 +335,6 @@ sync_array_reserve_cell( } cell->request_type = type; - cell->waiting = FALSE; cell->file = file; cell->line = line; @@ -373,6 +344,13 @@ sync_array_reserve_cell( *index = i; sync_array_exit(arr); + + /* Make sure the event is reset */ + sync_cell_event_reset(type, object); + + cell->reservation_time = time(NULL); + + cell->thread = os_thread_get_curr_id(); return; } @@ -408,7 +386,12 @@ sync_array_wait_event( ut_a(!cell->waiting); ut_ad(os_thread_get_curr_id() == cell->thread); - event = cell->event; + if (cell->request_type == SYNC_MUTEX) { + event = ((mutex_t*) cell->wait_object)->event; + } else { + event = ((rw_lock_t*) cell->wait_object)->event; + } + cell->waiting = TRUE; #ifdef UNIV_SYNC_DEBUG @@ -510,10 +493,6 @@ sync_array_cell_print( if (!cell->waiting) { fputs("wait has ended\n", file); } - - if (cell->event_set) { - fputs("wait is ending\n", file); - } } #ifdef UNIV_SYNC_DEBUG @@ -623,7 +602,7 @@ sync_array_detect_deadlock( depth++; - if (cell->event_set || !cell->waiting) { + if (!cell->waiting) { return(FALSE); /* No deadlock here */ } @@ -802,6 +781,7 @@ sync_array_free_cell( ut_a(cell->wait_object != NULL); + cell->waiting = FALSE; cell->wait_object = NULL; ut_a(arr->n_reserved > 0); @@ -811,44 +791,17 @@ sync_array_free_cell( } /************************************************************************** -Looks for the cells in the wait array which refer to the wait object -specified, and sets their corresponding events to the signaled state. In this -way releases the threads waiting for the object to contend for the object. -It is possible that no such cell is found, in which case does nothing. */ +Increments the signalled count. */ void -sync_array_signal_object( -/*=====================*/ - sync_array_t* arr, /* in: wait array */ - void* object) /* in: wait object */ +sync_array_object_signalled( +/*========================*/ + sync_array_t* arr) /* in: wait array */ { - sync_cell_t* cell; - ulint count; - ulint i; - sync_array_enter(arr); arr->sg_count++; - i = 0; - count = 0; - - while (count < arr->n_reserved) { - - cell = sync_array_get_nth_cell(arr, i); - - if (cell->wait_object != NULL) { - - count++; - if (cell->wait_object == object) { - - sync_cell_event_set(cell); - } - } - - i++; - } - sync_array_exit(arr); } @@ -881,7 +834,17 @@ sync_arr_wake_threads_if_sema_free(void) if (sync_arr_cell_can_wake_up(cell)) { - sync_cell_event_set(cell); + if (cell->request_type == SYNC_MUTEX) { + mutex_t* mutex; + + mutex = cell->wait_object; + os_event_set(mutex->event); + } else { + rw_lock_t* lock; + + lock = cell->wait_object; + os_event_set(lock->event); + } } } @@ -911,7 +874,7 @@ sync_array_print_long_waits(void) cell = sync_array_get_nth_cell(sync_primary_wait_array, i); - if (cell->wait_object != NULL + if (cell->wait_object != NULL && cell->waiting && difftime(time(NULL), cell->reservation_time) > 240) { fputs("InnoDB: Warning: a long semaphore wait:\n", stderr); @@ -919,7 +882,7 @@ sync_array_print_long_waits(void) noticed = TRUE; } - if (cell->wait_object != NULL + if (cell->wait_object != NULL && cell->waiting && difftime(time(NULL), cell->reservation_time) > fatal_timeout) { fatal = TRUE; diff --git a/innobase/sync/sync0rw.c b/innobase/sync/sync0rw.c index 973b46fdd50..050de73db9e 100644 --- a/innobase/sync/sync0rw.c +++ b/innobase/sync/sync0rw.c @@ -128,6 +128,7 @@ rw_lock_create_func( lock->last_x_file_name = "not yet reserved"; lock->last_s_line = 0; lock->last_x_line = 0; + lock->event = os_event_create(NULL); mutex_enter(&rw_lock_list_mutex); @@ -163,6 +164,7 @@ rw_lock_free( mutex_free(rw_lock_get_mutex(lock)); mutex_enter(&rw_lock_list_mutex); + os_event_free(lock->event); if (UT_LIST_GET_PREV(list, lock)) { ut_a(UT_LIST_GET_PREV(list, lock)->magic_n == RW_LOCK_MAGIC_N); diff --git a/innobase/sync/sync0sync.c b/innobase/sync/sync0sync.c index 43249f4b96f..95bf83dce79 100644 --- a/innobase/sync/sync0sync.c +++ b/innobase/sync/sync0sync.c @@ -212,6 +212,7 @@ mutex_create_func( os_fast_mutex_init(&(mutex->os_fast_mutex)); mutex->lock_word = 0; #endif + mutex->event = os_event_create(NULL); mutex_set_waiters(mutex, 0); mutex->magic_n = MUTEX_MAGIC_N; #ifdef UNIV_SYNC_DEBUG @@ -288,6 +289,8 @@ mutex_free( mutex_exit(&mutex_list_mutex); } + os_event_free(mutex->event); + #if !defined(_WIN32) || !defined(UNIV_CAN_USE_X86_ASSEMBLER) os_fast_mutex_free(&(mutex->os_fast_mutex)); #endif @@ -564,8 +567,8 @@ mutex_signal_object( /* The memory order of resetting the waiters field and signaling the object is important. See LEMMA 1 above. */ - - sync_array_signal_object(sync_primary_wait_array, mutex); + os_event_set(mutex->event); + sync_array_object_signalled(sync_primary_wait_array); } #ifdef UNIV_SYNC_DEBUG @@ -1114,6 +1117,7 @@ sync_thread_add_level( ut_a(sync_thread_levels_g(array, SYNC_PURGE_SYS)); } else if (level == SYNC_TREE_NODE) { ut_a(sync_thread_levels_contain(array, SYNC_INDEX_TREE) + || sync_thread_levels_contain(array, SYNC_DICT_OPERATION) || sync_thread_levels_g(array, SYNC_TREE_NODE - 1)); } else if (level == SYNC_TREE_NODE_FROM_HASH) { ut_a(1); diff --git a/mysql-test/include/report-features.test b/mysql-test/include/report-features.test new file mode 100644 index 00000000000..df395f6e3f0 --- /dev/null +++ b/mysql-test/include/report-features.test @@ -0,0 +1,11 @@ +# +# show server variables +# + +--disable_query_log +--echo ===== ENGINES ===== +show engines; +--echo ===== VARIABLES ===== +show variables; +--echo ===== STOP ===== +--enable_query_log diff --git a/mysql-test/install_test_db.sh b/mysql-test/install_test_db.sh index 4554b92857e..c30583503dc 100644 --- a/mysql-test/install_test_db.sh +++ b/mysql-test/install_test_db.sh @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (C) 1997-2002 MySQL AB +# Copyright (C) 1997-2006 MySQL AB # For a more info consult the file COPYRIGHT distributed with this file # This scripts creates the privilege tables db, host, user, tables_priv, @@ -7,19 +7,26 @@ if [ x$1 = x"--bin" ]; then shift 1 + BINARY_DIST=1 + + bindir=../bin + scriptdir=../bin + libexecdir=../libexec # Check if it's a binary distribution or a 'make install' if test -x ../libexec/mysqld then execdir=../libexec + elif test -x ../../sbin/mysqld # RPM installation + then + execdir=../../sbin + bindir=../../bin + scriptdir=../../bin + libexecdir=../../libexec else execdir=../bin fi - bindir=../bin - BINARY_DIST=1 fix_bin=mysql-test - scriptdir=../bin - libexecdir=../libexec else execdir=../sql bindir=../client diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 3aeca32f2e8..47de5901d13 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -185,7 +185,7 @@ our $opt_fast; our $opt_force; our $opt_reorder= 0; our $opt_enable_disabled; -our $opt_mem; +our $opt_mem= $ENV{'MTR_MEM'}; our $opt_gcov; our $opt_gcov_err; @@ -220,6 +220,7 @@ our $opt_ndbconnectstring_slave; our $opt_record; our $opt_check_testcases; +my $opt_report_features; our $opt_skip; our $opt_skip_rpl; @@ -426,10 +427,14 @@ sub main () { if ( ! $need_im ) { $opt_skip_im= 1; - } + } initialize_servers(); + if ( $opt_report_features ) { + run_report_features(); + } + run_suite($opt_suite, $tests); } @@ -591,9 +596,10 @@ sub command_line_setup () { 'tmpdir=s' => \$opt_tmpdir, 'vardir=s' => \$opt_vardir, 'benchdir=s' => \$glob_mysql_bench_dir, - 'mem' => \$opt_mem, + 'mem:s' => \$opt_mem, # Misc + 'report-features' => \$opt_report_features, 'comment=s' => \$opt_comment, 'debug' => \$opt_debug, 'fast' => \$opt_fast, @@ -637,7 +643,7 @@ sub command_line_setup () { $glob_hostname= mtr_short_hostname(); - # 'basedir' is always parent of "mysql-test" directory + # 'basedir' is always above "mysql-test" directory ... $glob_mysql_test_dir= cwd(); if ( $glob_cygwin_perl ) { @@ -645,11 +651,19 @@ sub command_line_setup () { $glob_mysql_test_dir= `cygpath -m "$glob_mysql_test_dir"`; chomp($glob_mysql_test_dir); } + # ... direct parent for "tar.gz" installations, ... $glob_basedir= dirname($glob_mysql_test_dir); + # ... or one more level up, for RPM installations. + if ( ! -d "$glob_basedir/bin" ) + { + $glob_basedir= dirname($glob_basedir); + } # Expect mysql-bench to be located adjacent to the source tree, by default $glob_mysql_bench_dir= "$glob_basedir/../mysql-bench" unless defined $glob_mysql_bench_dir; + $glob_mysql_bench_dir= undef + unless -d $glob_mysql_bench_dir; $path_my_basedir= $opt_source_dist ? $glob_mysql_test_dir : $glob_basedir; @@ -677,7 +691,8 @@ sub command_line_setup () { "$path_client_bindir/mysqld-debug", "$path_client_bindir/mysqld-max", "$glob_basedir/libexec/mysqld", - "$glob_basedir/bin/mysqld"); + "$glob_basedir/bin/mysqld", + "$glob_basedir/sbin/mysqld"); # Use the mysqld found above to find out what features are available collect_mysqld_features(); @@ -734,17 +749,18 @@ sub command_line_setup () { # -------------------------------------------------------------------------- # Check if we should speed up tests by trying to run on tmpfs # -------------------------------------------------------------------------- - if ( $opt_mem ) + if ( defined $opt_mem ) { mtr_error("Can't use --mem and --vardir at the same time ") if $opt_vardir; mtr_error("Can't use --mem and --tmpdir at the same time ") if $opt_tmpdir; - # Use /dev/shm as the preferred location for vardir and - # thus implicitly also tmpdir. Add other locations to list - my @tmpfs_locations= ("/dev/shm"); - # One could maybe use "mount" to find tmpfs location(s) + # Search through list of locations that are known + # to be "fast disks" to list to find a suitable location + # Use --mem=<dir> as first location to look. + my @tmpfs_locations= ($opt_mem, "/dev/shm", "/tmp"); + foreach my $fs (@tmpfs_locations) { if ( -d $fs ) @@ -793,6 +809,13 @@ sub command_line_setup () { $opt_vardir= "$glob_mysql_test_dir/$opt_vardir"; } + # Ensure a proper error message + mkpath("$opt_vardir"); + unless ( -d $opt_vardir and -w $opt_vardir ) + { + mtr_error("Writable 'var' directory is needed, use the '--vardir' option"); + } + # -------------------------------------------------------------------------- # Set tmpdir # -------------------------------------------------------------------------- @@ -1314,7 +1337,9 @@ sub executable_setup_im () { $exe_im= mtr_exe_maybe_exists( "$glob_basedir/server-tools/instance-manager/mysqlmanager", - "$glob_basedir/libexec/mysqlmanager"); + "$glob_basedir/libexec/mysqlmanager", + "$glob_basedir/bin/mysqlmanager", + "$glob_basedir/sbin/mysqlmanager"); return ($exe_im eq ""); } @@ -2988,9 +3013,9 @@ sub analyze_testcase_failure_sync_with_master($) mtr_add_arg($args, "--no-defaults"); mtr_add_arg($args, "--silent"); - mtr_add_arg($args, "-v"); mtr_add_arg($args, "--skip-safemalloc"); mtr_add_arg($args, "--tmpdir=%s", $opt_tmpdir); + mtr_add_arg($args, "--character-sets-dir=%s", $path_charsetsdir); mtr_add_arg($args, "--socket=%s", $master->[0]->{'path_sock'}); mtr_add_arg($args, "--port=%d", $master->[0]->{'port'}); @@ -3361,6 +3386,11 @@ sub mysqld_arguments ($$$$$) { if ( $opt_valgrind_mysqld ) { mtr_add_arg($args, "%s--skip-safemalloc", $prefix); + + if ( $mysql_version_id < 50100 ) + { + mtr_add_arg($args, "%s--skip-bdb", $prefix); + } } my $pidfile; @@ -4169,9 +4199,9 @@ sub run_check_testcase ($$) { mtr_add_arg($args, "--no-defaults"); mtr_add_arg($args, "--silent"); - mtr_add_arg($args, "-v"); mtr_add_arg($args, "--skip-safemalloc"); mtr_add_arg($args, "--tmpdir=%s", $opt_tmpdir); + mtr_add_arg($args, "--character-sets-dir=%s", $path_charsetsdir); mtr_add_arg($args, "--socket=%s", $mysqld->{'path_sock'}); mtr_add_arg($args, "--port=%d", $mysqld->{'port'}); @@ -4204,6 +4234,43 @@ sub run_check_testcase ($$) { return $res; } +############################################################################## +# +# Report the features that were compiled in +# +############################################################################## + +sub run_report_features () { + my $args; + + if ( ! $glob_use_embedded_server ) + { + mysqld_start($master->[0],[],[]); + if ( ! $master->[0]->{'pid'} ) + { + mtr_error("Can't start the mysqld server"); + } + mysqld_wait_started($master->[0]); + } + + my $tinfo = {}; + $tinfo->{'name'} = 'report features'; + $tinfo->{'result_file'} = undef; + $tinfo->{'component_id'} = 'mysqld'; + $tinfo->{'path'} = 'include/report-features.test'; + $tinfo->{'timezone'}= "GMT-3"; + $tinfo->{'slave_num'} = 0; + $tinfo->{'master_opt'} = []; + $tinfo->{'slave_opt'} = []; + $tinfo->{'slave_mi'} = []; + $tinfo->{'comment'} = 'report server features'; + run_mysqltest($tinfo); + + if ( ! $glob_use_embedded_server ) + { + stop_all_servers(); + } +} sub run_mysqltest ($) { @@ -4215,9 +4282,9 @@ sub run_mysqltest ($) { mtr_add_arg($args, "--no-defaults"); mtr_add_arg($args, "--silent"); - mtr_add_arg($args, "-v"); mtr_add_arg($args, "--skip-safemalloc"); mtr_add_arg($args, "--tmpdir=%s", $opt_tmpdir); + mtr_add_arg($args, "--character-sets-dir=%s", $path_charsetsdir); if ($tinfo->{'component_id'} eq 'im') { @@ -4302,13 +4369,11 @@ sub run_mysqltest ($) { if ( $opt_ssl ) { # Turn on SSL for _all_ test cases if option --ssl was used - mtr_add_arg($args, "--ssl", - $glob_mysql_test_dir); + mtr_add_arg($args, "--ssl"); } elsif ( $opt_ssl_supported ) { - mtr_add_arg($args, "--skip-ssl", - $glob_mysql_test_dir); + mtr_add_arg($args, "--skip-ssl"); } # ---------------------------------------------------------------------- @@ -4343,8 +4408,10 @@ sub run_mysqltest ($) { mtr_add_arg($args, "--test-file"); mtr_add_arg($args, $tinfo->{'path'}); - mtr_add_arg($args, "--result-file"); - mtr_add_arg($args, $tinfo->{'result_file'}); + if ( defined $tinfo->{'result_file'} ) { + mtr_add_arg($args, "--result-file"); + mtr_add_arg($args, $tinfo->{'result_file'}); + } if ( $opt_record ) { @@ -4643,9 +4710,12 @@ Options to control directories to use vardir=DIR The directory where files generated from the test run is stored (default: ./var). Specifying a ramdisk or tmpfs will speed up tests. - mem=DIR Run testsuite in "memory" using tmpfs if - available(default: /dev/shm) - + mem[=DIR] Run testsuite in "memory" using tmpfs or ramdisk + Attempts to use DIR first if specified else + uses as builtin list of standard locations + for tmpfs (/dev/shm) + The option can also be set using environment + variable MTR_MEM=[DIR] Options to control what test suites or cases to run @@ -4755,3 +4825,4 @@ HERE mtr_exit(1); } + diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 590885b3d46..52e98304aca 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -174,18 +174,29 @@ fi # Misc. Definitions #-- -if [ -d ../sql ] ; then +# BASEDIR is always above mysql-test directory ... +MYSQL_TEST_DIR=`pwd` +cd .. + +if [ -d ./sql ] ; then SOURCE_DIST=1 else BINARY_DIST=1 fi -#BASEDIR is always one above mysql-test directory -CWD=`pwd` -cd .. -BASEDIR=`pwd` -cd $CWD -MYSQL_TEST_DIR=$BASEDIR/mysql-test +# ... one level for tar.gz, two levels for a RPM installation +if [ -d ./bin ] ; then + # this is not perfect: we have + # /usr/share/mysql/ # mysql-test-run is here, so this is "$MYSQL_TEST_DIR" + # /usr/bin/ # with MySQL client programs + # so the existence of "/usr/share/bin/" would make this test fail. + BASEDIR=`pwd` +else + cd .. + BASEDIR=`pwd` +fi + +cd $MYSQL_TEST_DIR MYSQL_TEST_WINDIR=$MYSQL_TEST_DIR MYSQLTEST_VARDIR=$MYSQL_TEST_DIR/var export MYSQL_TEST_DIR MYSQL_TEST_WINDIR MYSQLTEST_VARDIR @@ -744,8 +755,15 @@ else if test -x "$BASEDIR/libexec/mysqld" then MYSQLD="$VALGRIND $BASEDIR/libexec/mysqld" - else + elif test -x "$BASEDIR/bin/mysqld" + then MYSQLD="$VALGRIND $BASEDIR/bin/mysqld" + elif test -x "$BASEDIR/sbin/mysqld" + then + MYSQLD="$VALGRIND $BASEDIR/sbin/mysqld" + else + $ECHO "Fatal error: Cannot find program mysqld in $BASEDIR/{libexec,bin,sbin}" 1>&2 + exit 1 fi CLIENT_BINDIR="$BASEDIR/bin" if test -d "$BASEDIR/tests" @@ -1390,7 +1408,7 @@ start_master() then $ECHO "set args $master_args" > $GDB_MASTER_INIT$1 $ECHO "To start gdb for the master , type in another window:" - $ECHO "cd $CWD ; gdb -x $GDB_MASTER_INIT$1 $MASTER_MYSQLD" + $ECHO "cd $MYSQL_TEST_DIR ; gdb -x $GDB_MASTER_INIT$1 $MASTER_MYSQLD" wait_for_master=1500 else ( $ECHO set args $master_args; @@ -1508,7 +1526,7 @@ start_slave() then $ECHO "set args $slave_args" > $GDB_SLAVE_INIT echo "To start gdb for the slave, type in another window:" - echo "cd $CWD ; gdb -x $GDB_SLAVE_INIT $SLAVE_MYSQLD" + echo "cd $MYSQL_TEST_DIR ; gdb -x $GDB_SLAVE_INIT $SLAVE_MYSQLD" wait_for_slave=1500 else ( $ECHO set args $slave_args; @@ -1750,10 +1768,13 @@ run_testcase () --result-file=*) result_file=`$ECHO "$EXTRA_MASTER_OPT" | $SED -e "s;--result-file=;;"` result_file="r/$result_file.result" - # Note that this must be set to space, not "" for test-reset to -# work + # Note that this must be set to space, not "" for test-reset to work EXTRA_MASTER_OPT=" " ;; + --force-restart) + # Note that this must be set to space, not "" for test-reset to work + EXTRA_MASTER_OPT=" " + ;; esac stop_master stop_master 1 diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index c2c12f8d291..e5342eec54f 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -1148,4 +1148,759 @@ id select_type table type possible_keys key key_len ref rows Extra Warnings: Note 1003 select `test`.`t1`.`code` AS `code`,`test`.`t2`.`id` AS `id` from `test`.`t1` join `test`.`t2` where ((`test`.`t1`.`code` = _latin1'a12') and (length(`test`.`t1`.`code`) = 5)) DROP TABLE t1,t2; +select locate('he','hello',-2); +locate('he','hello',-2) +0 +select locate('lo','hello',-4294967295); +locate('lo','hello',-4294967295) +0 +select locate('lo','hello',4294967295); +locate('lo','hello',4294967295) +0 +select locate('lo','hello',-4294967296); +locate('lo','hello',-4294967296) +0 +select locate('lo','hello',4294967296); +locate('lo','hello',4294967296) +0 +select locate('lo','hello',-4294967297); +locate('lo','hello',-4294967297) +0 +select locate('lo','hello',4294967297); +locate('lo','hello',4294967297) +0 +select locate('lo','hello',-18446744073709551615); +locate('lo','hello',-18446744073709551615) +0 +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +select locate('lo','hello',18446744073709551615); +locate('lo','hello',18446744073709551615) +0 +select locate('lo','hello',-18446744073709551616); +locate('lo','hello',-18446744073709551616) +0 +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +select locate('lo','hello',18446744073709551616); +locate('lo','hello',18446744073709551616) +0 +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +select locate('lo','hello',-18446744073709551617); +locate('lo','hello',-18446744073709551617) +0 +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +select locate('lo','hello',18446744073709551617); +locate('lo','hello',18446744073709551617) +0 +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +select left('hello', 10); +left('hello', 10) +hello +select left('hello', 0); +left('hello', 0) + +select left('hello', -1); +left('hello', -1) + +select left('hello', -4294967295); +left('hello', -4294967295) + +select left('hello', 4294967295); +left('hello', 4294967295) +hello +select left('hello', -4294967296); +left('hello', -4294967296) + +select left('hello', 4294967296); +left('hello', 4294967296) +hello +select left('hello', -4294967297); +left('hello', -4294967297) + +select left('hello', 4294967297); +left('hello', 4294967297) +hello +select left('hello', -18446744073709551615); +left('hello', -18446744073709551615) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select left('hello', 18446744073709551615); +left('hello', 18446744073709551615) +hello +select left('hello', -18446744073709551616); +left('hello', -18446744073709551616) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select left('hello', 18446744073709551616); +left('hello', 18446744073709551616) +hello +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select left('hello', -18446744073709551617); +left('hello', -18446744073709551617) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select left('hello', 18446744073709551617); +left('hello', 18446744073709551617) +hello +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select right('hello', 10); +right('hello', 10) +hello +select right('hello', 0); +right('hello', 0) + +select right('hello', -1); +right('hello', -1) + +select right('hello', -4294967295); +right('hello', -4294967295) + +select right('hello', 4294967295); +right('hello', 4294967295) +hello +select right('hello', -4294967296); +right('hello', -4294967296) + +select right('hello', 4294967296); +right('hello', 4294967296) +hello +select right('hello', -4294967297); +right('hello', -4294967297) + +select right('hello', 4294967297); +right('hello', 4294967297) +hello +select right('hello', -18446744073709551615); +right('hello', -18446744073709551615) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select right('hello', 18446744073709551615); +right('hello', 18446744073709551615) +hello +select right('hello', -18446744073709551616); +right('hello', -18446744073709551616) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select right('hello', 18446744073709551616); +right('hello', 18446744073709551616) +hello +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select right('hello', -18446744073709551617); +right('hello', -18446744073709551617) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select right('hello', 18446744073709551617); +right('hello', 18446744073709551617) +hello +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select substring('hello', 2, -1); +substring('hello', 2, -1) + +select substring('hello', -1, 1); +substring('hello', -1, 1) +o +select substring('hello', -2, 1); +substring('hello', -2, 1) +l +select substring('hello', -4294967295, 1); +substring('hello', -4294967295, 1) + +select substring('hello', 4294967295, 1); +substring('hello', 4294967295, 1) + +select substring('hello', -4294967296, 1); +substring('hello', -4294967296, 1) + +select substring('hello', 4294967296, 1); +substring('hello', 4294967296, 1) + +select substring('hello', -4294967297, 1); +substring('hello', -4294967297, 1) + +select substring('hello', 4294967297, 1); +substring('hello', 4294967297, 1) + +select substring('hello', -18446744073709551615, 1); +substring('hello', -18446744073709551615, 1) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select substring('hello', 18446744073709551615, 1); +substring('hello', 18446744073709551615, 1) + +select substring('hello', -18446744073709551616, 1); +substring('hello', -18446744073709551616, 1) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select substring('hello', 18446744073709551616, 1); +substring('hello', 18446744073709551616, 1) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select substring('hello', -18446744073709551617, 1); +substring('hello', -18446744073709551617, 1) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select substring('hello', 18446744073709551617, 1); +substring('hello', 18446744073709551617, 1) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select substring('hello', 1, -1); +substring('hello', 1, -1) + +select substring('hello', 1, -4294967295); +substring('hello', 1, -4294967295) + +select substring('hello', 1, 4294967295); +substring('hello', 1, 4294967295) +hello +select substring('hello', 1, -4294967296); +substring('hello', 1, -4294967296) + +select substring('hello', 1, 4294967296); +substring('hello', 1, 4294967296) +hello +select substring('hello', 1, -4294967297); +substring('hello', 1, -4294967297) + +select substring('hello', 1, 4294967297); +substring('hello', 1, 4294967297) +hello +select substring('hello', 1, -18446744073709551615); +substring('hello', 1, -18446744073709551615) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select substring('hello', 1, 18446744073709551615); +substring('hello', 1, 18446744073709551615) +hello +select substring('hello', 1, -18446744073709551616); +substring('hello', 1, -18446744073709551616) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select substring('hello', 1, 18446744073709551616); +substring('hello', 1, 18446744073709551616) +hello +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select substring('hello', 1, -18446744073709551617); +substring('hello', 1, -18446744073709551617) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select substring('hello', 1, 18446744073709551617); +substring('hello', 1, 18446744073709551617) +hello +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select substring('hello', -1, -1); +substring('hello', -1, -1) + +select substring('hello', -4294967295, -4294967295); +substring('hello', -4294967295, -4294967295) + +select substring('hello', 4294967295, 4294967295); +substring('hello', 4294967295, 4294967295) + +select substring('hello', -4294967296, -4294967296); +substring('hello', -4294967296, -4294967296) + +select substring('hello', 4294967296, 4294967296); +substring('hello', 4294967296, 4294967296) + +select substring('hello', -4294967297, -4294967297); +substring('hello', -4294967297, -4294967297) + +select substring('hello', 4294967297, 4294967297); +substring('hello', 4294967297, 4294967297) + +select substring('hello', -18446744073709551615, -18446744073709551615); +substring('hello', -18446744073709551615, -18446744073709551615) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select substring('hello', 18446744073709551615, 18446744073709551615); +substring('hello', 18446744073709551615, 18446744073709551615) + +select substring('hello', -18446744073709551616, -18446744073709551616); +substring('hello', -18446744073709551616, -18446744073709551616) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select substring('hello', 18446744073709551616, 18446744073709551616); +substring('hello', 18446744073709551616, 18446744073709551616) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select substring('hello', -18446744073709551617, -18446744073709551617); +substring('hello', -18446744073709551617, -18446744073709551617) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select substring('hello', 18446744073709551617, 18446744073709551617); +substring('hello', 18446744073709551617, 18446744073709551617) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select insert('hello', -1, 1, 'hi'); +insert('hello', -1, 1, 'hi') +hello +select insert('hello', -4294967295, 1, 'hi'); +insert('hello', -4294967295, 1, 'hi') +hello +select insert('hello', 4294967295, 1, 'hi'); +insert('hello', 4294967295, 1, 'hi') +hello +select insert('hello', -4294967296, 1, 'hi'); +insert('hello', -4294967296, 1, 'hi') +hello +select insert('hello', 4294967296, 1, 'hi'); +insert('hello', 4294967296, 1, 'hi') +hello +select insert('hello', -4294967297, 1, 'hi'); +insert('hello', -4294967297, 1, 'hi') +hello +select insert('hello', 4294967297, 1, 'hi'); +insert('hello', 4294967297, 1, 'hi') +hello +select insert('hello', -18446744073709551615, 1, 'hi'); +insert('hello', -18446744073709551615, 1, 'hi') +hello +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +select insert('hello', 18446744073709551615, 1, 'hi'); +insert('hello', 18446744073709551615, 1, 'hi') +hello +select insert('hello', -18446744073709551616, 1, 'hi'); +insert('hello', -18446744073709551616, 1, 'hi') +hello +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +select insert('hello', 18446744073709551616, 1, 'hi'); +insert('hello', 18446744073709551616, 1, 'hi') +hello +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +select insert('hello', -18446744073709551617, 1, 'hi'); +insert('hello', -18446744073709551617, 1, 'hi') +hello +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +select insert('hello', 18446744073709551617, 1, 'hi'); +insert('hello', 18446744073709551617, 1, 'hi') +hello +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +select insert('hello', 1, -1, 'hi'); +insert('hello', 1, -1, 'hi') +hi +select insert('hello', 1, -4294967295, 'hi'); +insert('hello', 1, -4294967295, 'hi') +hi +select insert('hello', 1, 4294967295, 'hi'); +insert('hello', 1, 4294967295, 'hi') +hi +select insert('hello', 1, -4294967296, 'hi'); +insert('hello', 1, -4294967296, 'hi') +hi +select insert('hello', 1, 4294967296, 'hi'); +insert('hello', 1, 4294967296, 'hi') +hi +select insert('hello', 1, -4294967297, 'hi'); +insert('hello', 1, -4294967297, 'hi') +hi +select insert('hello', 1, 4294967297, 'hi'); +insert('hello', 1, 4294967297, 'hi') +hi +select insert('hello', 1, -18446744073709551615, 'hi'); +insert('hello', 1, -18446744073709551615, 'hi') +hi +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +select insert('hello', 1, 18446744073709551615, 'hi'); +insert('hello', 1, 18446744073709551615, 'hi') +hi +select insert('hello', 1, -18446744073709551616, 'hi'); +insert('hello', 1, -18446744073709551616, 'hi') +hi +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +select insert('hello', 1, 18446744073709551616, 'hi'); +insert('hello', 1, 18446744073709551616, 'hi') +hi +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +select insert('hello', 1, -18446744073709551617, 'hi'); +insert('hello', 1, -18446744073709551617, 'hi') +hi +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +select insert('hello', 1, 18446744073709551617, 'hi'); +insert('hello', 1, 18446744073709551617, 'hi') +hi +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +select insert('hello', -1, -1, 'hi'); +insert('hello', -1, -1, 'hi') +hello +select insert('hello', -4294967295, -4294967295, 'hi'); +insert('hello', -4294967295, -4294967295, 'hi') +hello +select insert('hello', 4294967295, 4294967295, 'hi'); +insert('hello', 4294967295, 4294967295, 'hi') +hello +select insert('hello', -4294967296, -4294967296, 'hi'); +insert('hello', -4294967296, -4294967296, 'hi') +hello +select insert('hello', 4294967296, 4294967296, 'hi'); +insert('hello', 4294967296, 4294967296, 'hi') +hello +select insert('hello', -4294967297, -4294967297, 'hi'); +insert('hello', -4294967297, -4294967297, 'hi') +hello +select insert('hello', 4294967297, 4294967297, 'hi'); +insert('hello', 4294967297, 4294967297, 'hi') +hello +select insert('hello', -18446744073709551615, -18446744073709551615, 'hi'); +insert('hello', -18446744073709551615, -18446744073709551615, 'hi') +hello +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select insert('hello', 18446744073709551615, 18446744073709551615, 'hi'); +insert('hello', 18446744073709551615, 18446744073709551615, 'hi') +hello +select insert('hello', -18446744073709551616, -18446744073709551616, 'hi'); +insert('hello', -18446744073709551616, -18446744073709551616, 'hi') +hello +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select insert('hello', 18446744073709551616, 18446744073709551616, 'hi'); +insert('hello', 18446744073709551616, 18446744073709551616, 'hi') +hello +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select insert('hello', -18446744073709551617, -18446744073709551617, 'hi'); +insert('hello', -18446744073709551617, -18446744073709551617, 'hi') +hello +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select insert('hello', 18446744073709551617, 18446744073709551617, 'hi'); +insert('hello', 18446744073709551617, 18446744073709551617, 'hi') +hello +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select repeat('hello', -1); +repeat('hello', -1) + +select repeat('hello', -4294967295); +repeat('hello', -4294967295) + +select repeat('hello', 4294967295); +repeat('hello', 4294967295) +NULL +Warnings: +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated +select repeat('hello', -4294967296); +repeat('hello', -4294967296) + +select repeat('hello', 4294967296); +repeat('hello', 4294967296) +NULL +Warnings: +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated +select repeat('hello', -4294967297); +repeat('hello', -4294967297) + +select repeat('hello', 4294967297); +repeat('hello', 4294967297) +NULL +Warnings: +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated +select repeat('hello', -18446744073709551615); +repeat('hello', -18446744073709551615) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select repeat('hello', 18446744073709551615); +repeat('hello', 18446744073709551615) +NULL +Warnings: +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated +select repeat('hello', -18446744073709551616); +repeat('hello', -18446744073709551616) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select repeat('hello', 18446744073709551616); +repeat('hello', 18446744073709551616) +NULL +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated +select repeat('hello', -18446744073709551617); +repeat('hello', -18446744073709551617) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select repeat('hello', 18446744073709551617); +repeat('hello', 18446744073709551617) +NULL +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated +select space(-1); +space(-1) + +select space(-4294967295); +space(-4294967295) + +select space(4294967295); +space(4294967295) +NULL +Warnings: +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated +select space(-4294967296); +space(-4294967296) + +select space(4294967296); +space(4294967296) +NULL +Warnings: +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated +select space(-4294967297); +space(-4294967297) + +select space(4294967297); +space(4294967297) +NULL +Warnings: +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated +select space(-18446744073709551615); +space(-18446744073709551615) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select space(18446744073709551615); +space(18446744073709551615) +NULL +Warnings: +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated +select space(-18446744073709551616); +space(-18446744073709551616) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select space(18446744073709551616); +space(18446744073709551616) +NULL +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated +select space(-18446744073709551617); +space(-18446744073709551617) + +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select space(18446744073709551617); +space(18446744073709551617) +NULL +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated +select rpad('hello', -1, '1'); +rpad('hello', -1, '1') +NULL +select rpad('hello', -4294967295, '1'); +rpad('hello', -4294967295, '1') +NULL +select rpad('hello', 4294967295, '1'); +rpad('hello', 4294967295, '1') +NULL +Warnings: +Warning 1301 Result of rpad() was larger than max_allowed_packet (1048576) - truncated +select rpad('hello', -4294967296, '1'); +rpad('hello', -4294967296, '1') +NULL +select rpad('hello', 4294967296, '1'); +rpad('hello', 4294967296, '1') +NULL +Warnings: +Warning 1301 Result of rpad() was larger than max_allowed_packet (1048576) - truncated +select rpad('hello', -4294967297, '1'); +rpad('hello', -4294967297, '1') +NULL +select rpad('hello', 4294967297, '1'); +rpad('hello', 4294967297, '1') +NULL +Warnings: +Warning 1301 Result of rpad() was larger than max_allowed_packet (1048576) - truncated +select rpad('hello', -18446744073709551615, '1'); +rpad('hello', -18446744073709551615, '1') +NULL +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select rpad('hello', 18446744073709551615, '1'); +rpad('hello', 18446744073709551615, '1') +NULL +Warnings: +Warning 1301 Result of rpad() was larger than max_allowed_packet (1048576) - truncated +select rpad('hello', -18446744073709551616, '1'); +rpad('hello', -18446744073709551616, '1') +NULL +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select rpad('hello', 18446744073709551616, '1'); +rpad('hello', 18446744073709551616, '1') +NULL +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1301 Result of rpad() was larger than max_allowed_packet (1048576) - truncated +select rpad('hello', -18446744073709551617, '1'); +rpad('hello', -18446744073709551617, '1') +NULL +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select rpad('hello', 18446744073709551617, '1'); +rpad('hello', 18446744073709551617, '1') +NULL +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1301 Result of rpad() was larger than max_allowed_packet (1048576) - truncated +select lpad('hello', -1, '1'); +lpad('hello', -1, '1') +NULL +select lpad('hello', -4294967295, '1'); +lpad('hello', -4294967295, '1') +NULL +select lpad('hello', 4294967295, '1'); +lpad('hello', 4294967295, '1') +NULL +Warnings: +Warning 1301 Result of lpad() was larger than max_allowed_packet (1048576) - truncated +select lpad('hello', -4294967296, '1'); +lpad('hello', -4294967296, '1') +NULL +select lpad('hello', 4294967296, '1'); +lpad('hello', 4294967296, '1') +NULL +Warnings: +Warning 1301 Result of lpad() was larger than max_allowed_packet (1048576) - truncated +select lpad('hello', -4294967297, '1'); +lpad('hello', -4294967297, '1') +NULL +select lpad('hello', 4294967297, '1'); +lpad('hello', 4294967297, '1') +NULL +Warnings: +Warning 1301 Result of lpad() was larger than max_allowed_packet (1048576) - truncated +select lpad('hello', -18446744073709551615, '1'); +lpad('hello', -18446744073709551615, '1') +NULL +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select lpad('hello', 18446744073709551615, '1'); +lpad('hello', 18446744073709551615, '1') +NULL +Warnings: +Warning 1301 Result of lpad() was larger than max_allowed_packet (1048576) - truncated +select lpad('hello', -18446744073709551616, '1'); +lpad('hello', -18446744073709551616, '1') +NULL +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select lpad('hello', 18446744073709551616, '1'); +lpad('hello', 18446744073709551616, '1') +NULL +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1301 Result of lpad() was larger than max_allowed_packet (1048576) - truncated +select lpad('hello', -18446744073709551617, '1'); +lpad('hello', -18446744073709551617, '1') +NULL +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +select lpad('hello', 18446744073709551617, '1'); +lpad('hello', 18446744073709551617, '1') +NULL +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1301 Result of lpad() was larger than max_allowed_packet (1048576) - truncated End of 5.0 tests diff --git a/mysql-test/r/func_test.result b/mysql-test/r/func_test.result index d9437f6c515..43832bdbccc 100644 --- a/mysql-test/r/func_test.result +++ b/mysql-test/r/func_test.result @@ -182,6 +182,81 @@ select 5.1 mod 3, 5.1 mod -3, -5.1 mod 3, -5.1 mod -3; select 5 mod 3, 5 mod -3, -5 mod 3, -5 mod -3; 5 mod 3 5 mod -3 -5 mod 3 -5 mod -3 2 2 -2 -2 +select (12%0) <=> null as '1'; +1 +1 +select (12%0) is null as '1'; +1 +1 +select 12%0 as 'NULL'; +NULL +NULL +select 12%2 as '0'; +0 +0 +select 12%NULL as 'NULL'; +NULL +NULL +select 12 % null as 'NULL'; +NULL +NULL +select null % 12 as 'NULL'; +NULL +NULL +select null % 0 as 'NULL'; +NULL +NULL +select 0 % null as 'NULL'; +NULL +NULL +select null % null as 'NULL'; +NULL +NULL +select (12 mod 0) <=> null as '1'; +1 +1 +select (12 mod 0) is null as '1'; +1 +1 +select 12 mod 0 as 'NULL'; +NULL +NULL +select 12 mod 2 as '0'; +0 +0 +select 12 mod null as 'NULL'; +NULL +NULL +select null mod 12 as 'NULL'; +NULL +NULL +select null mod 0 as 'NULL'; +NULL +NULL +select 0 mod null as 'NULL'; +NULL +NULL +select null mod null as 'NULL'; +NULL +NULL +select mod(12.0, 0) as 'NULL'; +NULL +NULL +select mod(12, 0.0) as 'NULL'; +NULL +NULL +select mod(12, NULL) as 'NULL'; +NULL +NULL +select mod(12.0, NULL) as 'NULL'; +NULL +NULL +select mod(NULL, 2) as 'NULL'; +NULL +NULL +select mod(NULL, 2.0) as 'NULL'; +NULL +NULL create table t1 (a int, b int); insert into t1 values (1,2), (2,3), (3,4), (4,5); select * from t1 where a not between 1 and 2; diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result index 8f9fd50eced..914fe25119f 100644 --- a/mysql-test/r/openssl_1.result +++ b/mysql-test/r/openssl_1.result @@ -47,7 +47,7 @@ drop table t1; mysqltest: Could not open connection 'default': 2026 SSL connection error mysqltest: Could not open connection 'default': 2026 SSL connection error mysqltest: Could not open connection 'default': 2026 SSL connection error -Error when connection to server using SSL:Unable to get private key from '' +SSL error: Unable to get private key from '' mysqltest: Could not open connection 'default': 2026 SSL connection error -Error when connection to server using SSL:Unable to get certificate from '' +SSL error: Unable to get certificate from '' mysqltest: Could not open connection 'default': 2026 SSL connection error diff --git a/mysql-test/r/rpl_view.result b/mysql-test/r/rpl_view.result index 601f3d9cd14..be03f3f080a 100644 --- a/mysql-test/r/rpl_view.result +++ b/mysql-test/r/rpl_view.result @@ -47,11 +47,11 @@ show binlog events limit 1,100; Log_name Pos Event_type Server_id End_log_pos Info slave-bin.000001 # Query 1 # use `test`; create table t1 (a int) slave-bin.000001 # Query 1 # use `test`; insert into t1 values (1) -slave-bin.000001 # Query 1 # use `test`; CREATE ALGORITHM=UNDEFINED DEFINER=root@localhost SQL SECURITY DEFINER VIEW v1 AS select a from t1 +slave-bin.000001 # Query 1 # use `test`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select a from t1 slave-bin.000001 # Query 1 # use `test`; insert into v1 values (2) slave-bin.000001 # Query 1 # use `test`; update v1 set a=3 where a=1 slave-bin.000001 # Query 1 # use `test`; delete from v1 where a=2 -slave-bin.000001 # Query 1 # use `test`; ALTER ALGORITHM=UNDEFINED DEFINER=root@localhost SQL SECURITY DEFINER VIEW v1 AS select a as b from t1 +slave-bin.000001 # Query 1 # use `test`; ALTER ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select a as b from t1 slave-bin.000001 # Query 1 # use `test`; drop view v1 slave-bin.000001 # Query 1 # use `test`; drop table t1 diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 45415882ac7..9622de96143 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -780,4 +780,193 @@ SELECT * FROM t1 INNER JOIN t2 ON code=id DROP TABLE t1,t2; +# +# Bug #10963 +# 4294967296 18446744073709551616 + +select locate('he','hello',-2); +select locate('lo','hello',-4294967295); +select locate('lo','hello',4294967295); +select locate('lo','hello',-4294967296); +select locate('lo','hello',4294967296); +select locate('lo','hello',-4294967297); +select locate('lo','hello',4294967297); +select locate('lo','hello',-18446744073709551615); +select locate('lo','hello',18446744073709551615); +select locate('lo','hello',-18446744073709551616); +select locate('lo','hello',18446744073709551616); +select locate('lo','hello',-18446744073709551617); +select locate('lo','hello',18446744073709551617); + +select left('hello', 10); +select left('hello', 0); +select left('hello', -1); +select left('hello', -4294967295); +select left('hello', 4294967295); +select left('hello', -4294967296); +select left('hello', 4294967296); +select left('hello', -4294967297); +select left('hello', 4294967297); +select left('hello', -18446744073709551615); +select left('hello', 18446744073709551615); +select left('hello', -18446744073709551616); +select left('hello', 18446744073709551616); +select left('hello', -18446744073709551617); +select left('hello', 18446744073709551617); + +select right('hello', 10); +select right('hello', 0); +select right('hello', -1); +select right('hello', -4294967295); +select right('hello', 4294967295); +select right('hello', -4294967296); +select right('hello', 4294967296); +select right('hello', -4294967297); +select right('hello', 4294967297); +select right('hello', -18446744073709551615); +select right('hello', 18446744073709551615); +select right('hello', -18446744073709551616); +select right('hello', 18446744073709551616); +select right('hello', -18446744073709551617); +select right('hello', 18446744073709551617); + +select substring('hello', 2, -1); + +select substring('hello', -1, 1); +select substring('hello', -2, 1); +select substring('hello', -4294967295, 1); +select substring('hello', 4294967295, 1); +select substring('hello', -4294967296, 1); +select substring('hello', 4294967296, 1); +select substring('hello', -4294967297, 1); +select substring('hello', 4294967297, 1); +select substring('hello', -18446744073709551615, 1); +select substring('hello', 18446744073709551615, 1); +select substring('hello', -18446744073709551616, 1); +select substring('hello', 18446744073709551616, 1); +select substring('hello', -18446744073709551617, 1); +select substring('hello', 18446744073709551617, 1); +select substring('hello', 1, -1); +select substring('hello', 1, -4294967295); +select substring('hello', 1, 4294967295); +select substring('hello', 1, -4294967296); +select substring('hello', 1, 4294967296); +select substring('hello', 1, -4294967297); +select substring('hello', 1, 4294967297); +select substring('hello', 1, -18446744073709551615); +select substring('hello', 1, 18446744073709551615); +select substring('hello', 1, -18446744073709551616); +select substring('hello', 1, 18446744073709551616); +select substring('hello', 1, -18446744073709551617); +select substring('hello', 1, 18446744073709551617); +select substring('hello', -1, -1); +select substring('hello', -4294967295, -4294967295); +select substring('hello', 4294967295, 4294967295); +select substring('hello', -4294967296, -4294967296); +select substring('hello', 4294967296, 4294967296); +select substring('hello', -4294967297, -4294967297); +select substring('hello', 4294967297, 4294967297); +select substring('hello', -18446744073709551615, -18446744073709551615); +select substring('hello', 18446744073709551615, 18446744073709551615); +select substring('hello', -18446744073709551616, -18446744073709551616); +select substring('hello', 18446744073709551616, 18446744073709551616); +select substring('hello', -18446744073709551617, -18446744073709551617); +select substring('hello', 18446744073709551617, 18446744073709551617); + +select insert('hello', -1, 1, 'hi'); +select insert('hello', -4294967295, 1, 'hi'); +select insert('hello', 4294967295, 1, 'hi'); +select insert('hello', -4294967296, 1, 'hi'); +select insert('hello', 4294967296, 1, 'hi'); +select insert('hello', -4294967297, 1, 'hi'); +select insert('hello', 4294967297, 1, 'hi'); +select insert('hello', -18446744073709551615, 1, 'hi'); +select insert('hello', 18446744073709551615, 1, 'hi'); +select insert('hello', -18446744073709551616, 1, 'hi'); +select insert('hello', 18446744073709551616, 1, 'hi'); +select insert('hello', -18446744073709551617, 1, 'hi'); +select insert('hello', 18446744073709551617, 1, 'hi'); +select insert('hello', 1, -1, 'hi'); +select insert('hello', 1, -4294967295, 'hi'); +select insert('hello', 1, 4294967295, 'hi'); +select insert('hello', 1, -4294967296, 'hi'); +select insert('hello', 1, 4294967296, 'hi'); +select insert('hello', 1, -4294967297, 'hi'); +select insert('hello', 1, 4294967297, 'hi'); +select insert('hello', 1, -18446744073709551615, 'hi'); +select insert('hello', 1, 18446744073709551615, 'hi'); +select insert('hello', 1, -18446744073709551616, 'hi'); +select insert('hello', 1, 18446744073709551616, 'hi'); +select insert('hello', 1, -18446744073709551617, 'hi'); +select insert('hello', 1, 18446744073709551617, 'hi'); +select insert('hello', -1, -1, 'hi'); +select insert('hello', -4294967295, -4294967295, 'hi'); +select insert('hello', 4294967295, 4294967295, 'hi'); +select insert('hello', -4294967296, -4294967296, 'hi'); +select insert('hello', 4294967296, 4294967296, 'hi'); +select insert('hello', -4294967297, -4294967297, 'hi'); +select insert('hello', 4294967297, 4294967297, 'hi'); +select insert('hello', -18446744073709551615, -18446744073709551615, 'hi'); +select insert('hello', 18446744073709551615, 18446744073709551615, 'hi'); +select insert('hello', -18446744073709551616, -18446744073709551616, 'hi'); +select insert('hello', 18446744073709551616, 18446744073709551616, 'hi'); +select insert('hello', -18446744073709551617, -18446744073709551617, 'hi'); +select insert('hello', 18446744073709551617, 18446744073709551617, 'hi'); + +select repeat('hello', -1); +select repeat('hello', -4294967295); +select repeat('hello', 4294967295); +select repeat('hello', -4294967296); +select repeat('hello', 4294967296); +select repeat('hello', -4294967297); +select repeat('hello', 4294967297); +select repeat('hello', -18446744073709551615); +select repeat('hello', 18446744073709551615); +select repeat('hello', -18446744073709551616); +select repeat('hello', 18446744073709551616); +select repeat('hello', -18446744073709551617); +select repeat('hello', 18446744073709551617); + +select space(-1); +select space(-4294967295); +select space(4294967295); +select space(-4294967296); +select space(4294967296); +select space(-4294967297); +select space(4294967297); +select space(-18446744073709551615); +select space(18446744073709551615); +select space(-18446744073709551616); +select space(18446744073709551616); +select space(-18446744073709551617); +select space(18446744073709551617); + +select rpad('hello', -1, '1'); +select rpad('hello', -4294967295, '1'); +select rpad('hello', 4294967295, '1'); +select rpad('hello', -4294967296, '1'); +select rpad('hello', 4294967296, '1'); +select rpad('hello', -4294967297, '1'); +select rpad('hello', 4294967297, '1'); +select rpad('hello', -18446744073709551615, '1'); +select rpad('hello', 18446744073709551615, '1'); +select rpad('hello', -18446744073709551616, '1'); +select rpad('hello', 18446744073709551616, '1'); +select rpad('hello', -18446744073709551617, '1'); +select rpad('hello', 18446744073709551617, '1'); + +select lpad('hello', -1, '1'); +select lpad('hello', -4294967295, '1'); +select lpad('hello', 4294967295, '1'); +select lpad('hello', -4294967296, '1'); +select lpad('hello', 4294967296, '1'); +select lpad('hello', -4294967297, '1'); +select lpad('hello', 4294967297, '1'); +select lpad('hello', -18446744073709551615, '1'); +select lpad('hello', 18446744073709551615, '1'); +select lpad('hello', -18446744073709551616, '1'); +select lpad('hello', 18446744073709551616, '1'); +select lpad('hello', -18446744073709551617, '1'); +select lpad('hello', 18446744073709551617, '1'); + --echo End of 5.0 tests diff --git a/mysql-test/t/func_test.test b/mysql-test/t/func_test.test index 0ea89cd0913..77bf3be5e72 100644 --- a/mysql-test/t/func_test.test +++ b/mysql-test/t/func_test.test @@ -108,6 +108,40 @@ select 5.1 mod 3, 5.1 mod -3, -5.1 mod 3, -5.1 mod -3; select 5 mod 3, 5 mod -3, -5 mod 3, -5 mod -3; +# +# Bug#23411: The "%" (MOD) operator is not documented; MOD-ing zero returns strange result +# Manual: "Division by zero produces a NULL result" +# +select (12%0) <=> null as '1'; +select (12%0) is null as '1'; +select 12%0 as 'NULL'; +select 12%2 as '0'; +select 12%NULL as 'NULL'; +select 12 % null as 'NULL'; +select null % 12 as 'NULL'; +select null % 0 as 'NULL'; +select 0 % null as 'NULL'; +select null % null as 'NULL'; + +select (12 mod 0) <=> null as '1'; +select (12 mod 0) is null as '1'; +select 12 mod 0 as 'NULL'; +select 12 mod 2 as '0'; +select 12 mod null as 'NULL'; +select null mod 12 as 'NULL'; +select null mod 0 as 'NULL'; +select 0 mod null as 'NULL'; +select null mod null as 'NULL'; + +select mod(12.0, 0) as 'NULL'; +select mod(12, 0.0) as 'NULL'; +select mod(12, NULL) as 'NULL'; +select mod(12.0, NULL) as 'NULL'; +select mod(NULL, 2) as 'NULL'; +select mod(NULL, 2.0) as 'NULL'; + + +# # Bug#6726: NOT BETWEEN parse failure # create table t1 (a int, b int); diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index d9e3ea27895..512e8a574ed 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -121,7 +121,7 @@ copyfileto() copyfileto $BASE/docs ChangeLog Docs/mysql.info copyfileto $BASE COPYING COPYING.LIB README Docs/INSTALL-BINARY \ - EXCEPTIONS-CLIENT MySQLEULA.txt LICENSE.doc README.NW + EXCEPTIONS-CLIENT LICENSE.mysql # Non platform-specific bin dir files: BIN_FILES="extra/comp_err$BS extra/replace$BS extra/perror$BS \ @@ -303,10 +303,7 @@ if [ $BASE_SYSTEM = "netware" ] ; then $BASE/support-files/build-tags \ $BASE/support-files/MySQL-shared-compat.spec \ $BASE/support-files/ndb-config-2-node.ini \ - $BASE/INSTALL-BINARY \ - $BASE/MySQLEULA.txt -else - rm -f $BASE/README.NW + $BASE/INSTALL-BINARY fi # Make safe_mysqld a symlink to mysqld_safe for backwards portability diff --git a/sql/item_func.cc b/sql/item_func.cc index a294bbd7a71..fa953889619 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -105,7 +105,7 @@ Item_func::Item_func(THD *thd, Item_func *item) /* - Resolve references to table column for a function and it's argument + Resolve references to table column for a function and its argument SYNOPSIS: fix_fields() @@ -1377,6 +1377,13 @@ void Item_func_mod::result_precision() } +void Item_func_mod::fix_length_and_dec() +{ + Item_num_op::fix_length_and_dec(); + maybe_null= 1; +} + + double Item_func_neg::real_op() { double value= args[0]->val_real(); @@ -2306,21 +2313,27 @@ longlong Item_func_locate::val_int() return 0; /* purecov: inspected */ } null_value=0; - uint start=0; - uint start0=0; + /* must be longlong to avoid truncation */ + longlong start= 0; + longlong start0= 0; my_match_t match; if (arg_count == 3) { - start0= start =(uint) args[2]->val_int()-1; - start=a->charpos(start); - - if (start > a->length() || start+b->length() > a->length()) + start0= start= args[2]->val_int() - 1; + + if ((start < 0) || (start > a->length())) + return 0; + + /* start is now sufficiently valid to pass to charpos function */ + start= a->charpos(start); + + if (start + b->length() > a->length()) return 0; } if (!b->length()) // Found empty string at start - return (longlong) (start+1); + return start + 1; if (!cmp_collation.collation->coll->instr(cmp_collation.collation, a->ptr()+start, a->length()-start, diff --git a/sql/item_func.h b/sql/item_func.h index 31adc033034..f887ba6a7cd 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -430,6 +430,7 @@ public: my_decimal *decimal_op(my_decimal *); const char *func_name() const { return "%"; } void result_precision(); + void fix_length_and_dec(); }; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 4f3e280fc8a..c2f16ffac10 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -951,22 +951,33 @@ String *Item_func_insert::val_str(String *str) { DBUG_ASSERT(fixed == 1); String *res,*res2; - uint start,length; + longlong start, length; /* must be longlong to avoid truncation */ null_value=0; res=args[0]->val_str(str); res2=args[3]->val_str(&tmp_value); - start=(uint) args[1]->val_int()-1; - length=(uint) args[2]->val_int(); + start= args[1]->val_int() - 1; + length= args[2]->val_int(); + if (args[0]->null_value || args[1]->null_value || args[2]->null_value || args[3]->null_value) goto null; /* purecov: inspected */ - start=res->charpos(start); - length=res->charpos(length,start); - if (start > res->length()+1) - return res; // Wrong param; skip insert - if (length > res->length()-start) - length=res->length()-start; + + if ((start < 0) || (start > res->length() + 1)) + return res; // Wrong param; skip insert + if ((length < 0) || (length > res->length() + 1)) + length= res->length() + 1; + + /* start and length are now sufficiently valid to pass to charpos function */ + start= res->charpos(start); + length= res->charpos(length, start); + + /* Re-testing with corrected params */ + if (start > res->length() + 1) + return res; // Wrong param; skip insert + if (length > res->length() - start) + length= res->length() - start; + if (res->length() - length + res2->length() > current_thd->variables.max_allowed_packet) { @@ -1039,16 +1050,21 @@ String *Item_str_conv::val_str(String *str) String *Item_func_left::val_str(String *str) { DBUG_ASSERT(fixed == 1); - String *res =args[0]->val_str(str); - long length =(long) args[1]->val_int(); + String *res= args[0]->val_str(str); + + /* must be longlong to avoid truncation */ + longlong length= args[1]->val_int(); uint char_pos; if ((null_value=(args[0]->null_value || args[1]->null_value))) return 0; - if (length <= 0) + + /* if "unsigned_flag" is set, we have a *huge* positive number. */ + if ((length <= 0) && (!args[1]->unsigned_flag)) return &my_empty_string; - if (res->length() <= (uint) length || - res->length() <= (char_pos= res->charpos(length))) + + if ((res->length() <= (ulonglong) length) || + (res->length() <= (char_pos= res->charpos(length)))) return res; tmp_value.set(*res, 0, char_pos); @@ -1080,14 +1096,18 @@ void Item_func_left::fix_length_and_dec() String *Item_func_right::val_str(String *str) { DBUG_ASSERT(fixed == 1); - String *res =args[0]->val_str(str); - long length =(long) args[1]->val_int(); + String *res= args[0]->val_str(str); + /* must be longlong to avoid truncation */ + longlong length= args[1]->val_int(); if ((null_value=(args[0]->null_value || args[1]->null_value))) return 0; /* purecov: inspected */ - if (length <= 0) + + /* if "unsigned_flag" is set, we have a *huge* positive number. */ + if ((length <= 0) && (!args[1]->unsigned_flag)) return &my_empty_string; /* purecov: inspected */ - if (res->length() <= (uint) length) + + if (res->length() <= (ulonglong) length) return res; /* purecov: inspected */ uint start=res->numchars(); @@ -1110,25 +1130,43 @@ String *Item_func_substr::val_str(String *str) { DBUG_ASSERT(fixed == 1); String *res = args[0]->val_str(str); - int32 start = (int32) args[1]->val_int(); - int32 length = arg_count == 3 ? (int32) args[2]->val_int() : INT_MAX32; - int32 tmp_length; + /* must be longlong to avoid truncation */ + longlong start= args[1]->val_int(); + /* Assumes that the maximum length of a String is < INT_MAX32. */ + /* Limit so that code sees out-of-bound value properly. */ + longlong length= arg_count == 3 ? args[2]->val_int() : INT_MAX32; + longlong tmp_length; if ((null_value=(args[0]->null_value || args[1]->null_value || (arg_count == 3 && args[2]->null_value)))) return 0; /* purecov: inspected */ - start= (int32)((start < 0) ? res->numchars() + start : start -1); - start=res->charpos(start); - length=res->charpos(length,start); - if (start < 0 || (uint) start+1 > res->length() || length <= 0) + + /* Negative length, will return empty string. */ + if ((arg_count == 3) && (length <= 0) && !args[2]->unsigned_flag) return &my_empty_string; - tmp_length=(int32) res->length()-start; - length=min(length,tmp_length); + /* Assumes that the maximum length of a String is < INT_MAX32. */ + /* Set here so that rest of code sees out-of-bound value as such. */ + if ((length <= 0) || (length > INT_MAX32)) + length= INT_MAX32; - if (!start && res->length() == (uint) length) + /* if "unsigned_flag" is set, we have a *huge* positive number. */ + /* Assumes that the maximum length of a String is < INT_MAX32. */ + if ((args[1]->unsigned_flag) || (start < INT_MIN32) || (start > INT_MAX32)) + return &my_empty_string; + + start= ((start < 0) ? res->numchars() + start : start - 1); + start= res->charpos(start); + if ((start < 0) || ((uint) start + 1 > res->length())) + return &my_empty_string; + + length= res->charpos(length, start); + tmp_length= res->length() - start; + length= min(length, tmp_length); + + if (!start && res->length() == (ulonglong) length) return res; - tmp_value.set(*res,(uint) start,(uint) length); + tmp_value.set(*res, (ulonglong) start, (ulonglong) length); return &tmp_value; } @@ -2141,8 +2179,15 @@ void Item_func_repeat::fix_length_and_dec() collation.set(args[0]->collation); if (args[1]->const_item()) { - ulonglong max_result_length= ((ulonglong) args[0]->max_length * - args[1]->val_int()); + /* must be longlong to avoid truncation */ + longlong count= args[1]->val_int(); + + /* Assumes that the maximum length of a String is < INT_MAX32. */ + /* Set here so that rest of code sees out-of-bound value as such. */ + if (count > INT_MAX32) + count= INT_MAX32; + + ulonglong max_result_length= (ulonglong) args[0]->max_length * count; if (max_result_length >= MAX_BLOB_WIDTH) { max_result_length= MAX_BLOB_WIDTH; @@ -2167,13 +2212,20 @@ String *Item_func_repeat::val_str(String *str) DBUG_ASSERT(fixed == 1); uint length,tot_length; char *to; - long count= (long) args[1]->val_int(); - String *res =args[0]->val_str(str); + /* must be longlong to avoid truncation */ + longlong tmp_count= args[1]->val_int(); + long count= tmp_count; + String *res= args[0]->val_str(str); + + /* Assumes that the maximum length of a String is < INT_MAX32. */ + /* Bounds check on count: If this is triggered, we will error. */ + if ((tmp_count > INT_MAX32) || args[1]->unsigned_flag) + count= INT_MAX32; if (args[0]->null_value || args[1]->null_value) goto err; // string and/or delim are null - null_value=0; - if (count <= 0) // For nicer SQL code + null_value= 0; + if ((tmp_count <= 0) && !args[1]->unsigned_flag) // For nicer SQL code return &my_empty_string; if (count == 1) // To avoid reallocs return res; @@ -2212,8 +2264,20 @@ void Item_func_rpad::fix_length_and_dec() return; if (args[1]->const_item()) { - ulonglong length= ((ulonglong) args[1]->val_int() * - collation.collation->mbmaxlen); + ulonglong length= 0; + + if (collation.collation->mbmaxlen > 0) + { + ulonglong temp= (ulonglong) args[1]->val_int(); + + /* Assumes that the maximum length of a String is < INT_MAX32. */ + /* Set here so that rest of code sees out-of-bound value as such. */ + if (temp > INT_MAX32) + temp = INT_MAX32; + + length= temp * collation.collation->mbmaxlen; + } + if (length >= MAX_BLOB_WIDTH) { length= MAX_BLOB_WIDTH; @@ -2235,21 +2299,30 @@ String *Item_func_rpad::val_str(String *str) uint32 res_byte_length,res_char_length,pad_char_length,pad_byte_length; char *to; const char *ptr_pad; - int32 count= (int32) args[1]->val_int(); - int32 byte_count= count * collation.collation->mbmaxlen; - String *res =args[0]->val_str(str); - String *rpad = args[2]->val_str(&rpad_str); + /* must be longlong to avoid truncation */ + longlong count= args[1]->val_int(); + longlong byte_count; + String *res= args[0]->val_str(str); + String *rpad= args[2]->val_str(&rpad_str); + + /* Assumes that the maximum length of a String is < INT_MAX32. */ + /* Set here so that rest of code sees out-of-bound value as such. */ + if ((count > INT_MAX32) || args[1]->unsigned_flag) + count= INT_MAX32; if (!res || args[1]->null_value || !rpad || count < 0) goto err; null_value=0; - if (count <= (int32) (res_char_length=res->numchars())) + + if (count <= (res_char_length= res->numchars())) { // String to pad is big enough res->length(res->charpos(count)); // Shorten result if longer return (res); } pad_char_length= rpad->numchars(); - if ((ulong) byte_count > current_thd->variables.max_allowed_packet) + + byte_count= count * collation.collation->mbmaxlen; + if ((ulonglong) byte_count > current_thd->variables.max_allowed_packet) { push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_ALLOWED_PACKET_OVERFLOWED, @@ -2295,8 +2368,20 @@ void Item_func_lpad::fix_length_and_dec() if (args[1]->const_item()) { - ulonglong length= ((ulonglong) args[1]->val_int() * - collation.collation->mbmaxlen); + ulonglong length= 0; + + if (collation.collation->mbmaxlen > 0) + { + ulonglong temp= (ulonglong) args[1]->val_int(); + + /* Assumes that the maximum length of a String is < INT_MAX32. */ + /* Set here so that rest of code sees out-of-bound value as such. */ + if (temp > INT_MAX32) + temp= INT_MAX32; + + length= temp * collation.collation->mbmaxlen; + } + if (length >= MAX_BLOB_WIDTH) { length= MAX_BLOB_WIDTH; @@ -2316,13 +2401,19 @@ String *Item_func_lpad::val_str(String *str) { DBUG_ASSERT(fixed == 1); uint32 res_char_length,pad_char_length; - ulong count= (long) args[1]->val_int(), byte_count; + /* must be longlong to avoid truncation */ + longlong count= args[1]->val_int(); + longlong byte_count; String *res= args[0]->val_str(&tmp_value); String *pad= args[2]->val_str(&lpad_str); - if (!res || args[1]->null_value || !pad) - goto err; + /* Assumes that the maximum length of a String is < INT_MAX32. */ + /* Set here so that rest of code sees out-of-bound value as such. */ + if ((count > INT_MAX32) || args[1]->unsigned_flag) + count= INT_MAX32; + if (!res || args[1]->null_value || !pad || count < 0) + goto err; null_value=0; res_char_length= res->numchars(); diff --git a/sql/slave.cc b/sql/slave.cc index 28bb7f12008..e3497a4f0ac 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2854,8 +2854,21 @@ improper_arguments: %d timed_out: %d", void set_slave_thread_options(THD* thd) { - thd->options = ((opt_log_slave_updates) ? OPTION_BIN_LOG:0) | - OPTION_AUTO_IS_NULL; + /* + It's nonsense to constrain the slave threads with max_join_size; if a + query succeeded on master, we HAVE to execute it. So set + OPTION_BIG_SELECTS. Setting max_join_size to HA_POS_ERROR is not enough + (and it's not needed if we have OPTION_BIG_SELECTS) because an INSERT + SELECT examining more than 4 billion rows would still fail (yes, because + when max_join_size is 4G, OPTION_BIG_SELECTS is automatically set, but + only for client threads. + */ + ulonglong options= thd->options | OPTION_BIG_SELECTS; + if (opt_log_slave_updates) + options|= OPTION_BIN_LOG; + else + options&= ~OPTION_BIN_LOG; + thd->options= options; thd->variables.completion_type= 0; } @@ -2885,17 +2898,6 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type) thd->net.read_timeout = slave_net_timeout; thd->slave_thread = 1; set_slave_thread_options(thd); - /* - It's nonsense to constrain the slave threads with max_join_size; if a - query succeeded on master, we HAVE to execute it. So set - OPTION_BIG_SELECTS. Setting max_join_size to HA_POS_ERROR is not enough - (and it's not needed if we have OPTION_BIG_SELECTS) because an INSERT - SELECT examining more than 4 billion rows would still fail (yes, because - when max_join_size is 4G, OPTION_BIG_SELECTS is automatically set, but - only for client threads. - */ - thd->options = ((opt_log_slave_updates) ? OPTION_BIN_LOG:0) | - OPTION_AUTO_IS_NULL | OPTION_BIG_SELECTS; thd->client_capabilities = CLIENT_LOCAL_FILES; thd->real_id=pthread_self(); pthread_mutex_lock(&LOCK_thread_count); diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 9fd18579351..34ce1fefaa9 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -86,8 +86,7 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file) if (SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) <= 0) { DBUG_PRINT("error",("unable to get certificate from '%s'\n", cert_file)); - /* FIX stderr */ - fprintf(stderr,"Error when connection to server using SSL:"); + fprintf(stderr,"SSL error: "); ERR_print_errors_fp(stderr); fprintf(stderr,"Unable to get certificate from '%s'\n", cert_file); fflush(stderr); @@ -100,8 +99,7 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file) if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0) { DBUG_PRINT("error", ("unable to get private key from '%s'\n", key_file)); - /* FIX stderr */ - fprintf(stderr,"Error when connection to server using SSL:"); + fprintf(stderr,"SSL error: "); ERR_print_errors_fp(stderr); fprintf(stderr,"Unable to get private key from '%s'\n", key_file); fflush(stderr); @@ -252,6 +250,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file, { DBUG_PRINT("error", ("failed to set ciphers to use")); report_errors(); + SSL_CTX_free(ssl_fd->ssl_context); my_free((void*)ssl_fd,MYF(0)); DBUG_RETURN(0); } @@ -264,6 +263,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file, { DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed")); report_errors(); + SSL_CTX_free(ssl_fd->ssl_context); my_free((void*)ssl_fd,MYF(0)); DBUG_RETURN(0); } @@ -273,6 +273,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file, { DBUG_PRINT("error", ("vio_set_cert_stuff failed")); report_errors(); + SSL_CTX_free(ssl_fd->ssl_context); my_free((void*)ssl_fd,MYF(0)); DBUG_RETURN(0); } |