summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BitKeeper/etc/collapsed2
-rw-r--r--Docs/MySQLEULA.txt252
-rw-r--r--README14
-rw-r--r--client/mysql_upgrade.c694
-rw-r--r--client/mysqltest.c20
-rw-r--r--configure.in4
-rw-r--r--include/abi_check0
-rw-r--r--include/abi_check.ic914
-rw-r--r--innobase/buf/buf0buf.c181
-rw-r--r--innobase/buf/buf0flu.c92
-rw-r--r--innobase/buf/buf0lru.c25
-rw-r--r--innobase/dict/dict0crea.c13
-rw-r--r--innobase/fil/fil0fil.c44
-rw-r--r--innobase/include/buf0buf.h40
-rw-r--r--innobase/include/buf0buf.ic19
-rw-r--r--innobase/include/dict0crea.h6
-rw-r--r--innobase/include/sync0arr.h13
-rw-r--r--innobase/include/sync0rw.h1
-rw-r--r--innobase/include/sync0rw.ic6
-rw-r--r--innobase/include/sync0sync.h1
-rw-r--r--innobase/os/os0sync.c55
-rw-r--r--innobase/row/row0mysql.c8
-rw-r--r--innobase/row/row0sel.c6
-rw-r--r--innobase/srv/srv0start.c5
-rw-r--r--innobase/sync/sync0arr.c119
-rw-r--r--innobase/sync/sync0rw.c2
-rw-r--r--innobase/sync/sync0sync.c8
-rw-r--r--mysql-test/include/report-features.test11
-rw-r--r--mysql-test/install_test_db.sh17
-rwxr-xr-xmysql-test/mysql-test-run.pl117
-rw-r--r--mysql-test/mysql-test-run.sh45
-rw-r--r--mysql-test/r/func_str.result755
-rw-r--r--mysql-test/r/func_test.result75
-rw-r--r--mysql-test/r/openssl_1.result4
-rw-r--r--mysql-test/r/rpl_view.result4
-rw-r--r--mysql-test/t/func_str.test189
-rw-r--r--mysql-test/t/func_test.test34
-rw-r--r--scripts/make_binary_distribution.sh7
-rw-r--r--sql/item_func.cc29
-rw-r--r--sql/item_func.h1
-rw-r--r--sql/item_strfunc.cc187
-rw-r--r--sql/slave.cc28
-rw-r--r--vio/viosslfactories.c9
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.
diff --git a/README b/README
index d37b37cd918..56bd912d3d6 100644
--- a/README
+++ b/README
@@ -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*) &current_host,
+ (gptr*) &current_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);
}