diff options
52 files changed, 1515 insertions, 216 deletions
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 82fa8244856..ed35a998fb7 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -36,6 +36,7 @@ lenz@kallisto.mysql.com lenz@mysql.com miguel@hegel.br miguel@hegel.local +miguel@light. miguel@light.local monty@bitch.mysql.fi monty@donna.mysql.fi @@ -55,6 +56,7 @@ nick@mysql.com nick@nick.leippe.com paul@central.snake.net paul@teton.kitebird.com +pem@mysql.com peter@linux.local peter@mysql.com ram@gw.udmsearch.izhnet.ru diff --git a/Build-tools/Do-compile b/Build-tools/Do-compile index 2e4da3091b0..9f62b617056 100755 --- a/Build-tools/Do-compile +++ b/Build-tools/Do-compile @@ -374,14 +374,14 @@ if ($opt_stage <= 9 && !$opt_no_test) log_system("rm -f output/*"); $tmp= $opt_fast_benchmark ? "--fast --user root --small-test" : ""; check_system("perl ./run-all-tests --log --die-on-errors $connect_option $tmp","RUN-mysql"); - if ($opt_bdb) - { - check_system("perl ./run-all-tests --log --suffix=\"_bdb\" --die-on-errors $connect_option $tmp --create-option=\"type=bdb\"","RUN-mysql"); - } if ($opt_innodb) { check_system("perl ./run-all-tests --log --suffix=\"_innodb\" --die-on-errors $connect_option $tmp --create-option=\"type=innodb\"","RUN-mysql"); } + if ($opt_bdb) + { + check_system("perl ./run-all-tests --log --suffix=\"_bdb\" --die-on-errors $connect_option $tmp --create-option=\"type=bdb\"","RUN-mysql"); + } } rm_all($bench_tmpdir); diff --git a/Build-tools/mysql-copyright b/Build-tools/mysql-copyright index 68673f3f53f..70b65d3f2cf 100755 --- a/Build-tools/mysql-copyright +++ b/Build-tools/mysql-copyright @@ -93,11 +93,11 @@ sub main $pec= $? >> 8; abort($dir, "Extracting from tar failed!\n") if ($pec); - # remove the 'PUBLIC' file from distribution and copy LICENSE + # remove the 'PUBLIC' file from distribution and copy MySQLEULA.txt # on the toplevel of the directory instead. file 'PUBLIC' shouldn't # exist in the new mysql distributions, but let's be sure.. `rm -f $destdir/PUBLIC $destdir/README`; - `cp -p $WD/Docs/LICENSE $destdir/`; + `cp -p $WD/Docs/MySQLEULA.txt $destdir/`; # fix file copyrights &fix_usage_copyright(); @@ -129,7 +129,7 @@ sub fix_usage_copyright foreach my $Cfile (@Cfiles) { chop $Cfile; - `replace "This is free software," "This is commercial software," "and you are welcome to modify and redistribute it under the GPL license" "please see the file LICENSE for details" -- $Cfile`; + `replace "This is free software," "This is commercial software," "and you are welcome to modify and redistribute it under the GPL license" "please see the file MySQLEULA.txt for details" -- $Cfile`; } } diff --git a/Build-tools/mysql-copyright-2 b/Build-tools/mysql-copyright-2 index a0d30f308e5..447a2d7c164 100755 --- a/Build-tools/mysql-copyright-2 +++ b/Build-tools/mysql-copyright-2 @@ -15,10 +15,10 @@ Getopts("v") || die "Aborted"; "This software is distributed with NO WARRANTY OF ANY KIND. No author or", "distributor accepts any responsibility for the consequences of using it, or", "for whether it serves any particular purpose or works at all, unless he or", - "she says so in writing. Refer to the LICENSE file for details.", + "she says so in writing. Refer to the MySQLEULA.txt file for details.", "", "Every copy of this file must include a copy of the License, normally in a", - "plain ASCII text file named LICENSE. The License grants you the right to", + "plain ASCII text file named MySQLEULA.txt. The License grants you the right to", "copy, modify and redistribute this file, but only under certain conditions", "described in the License. Among other things, the License requires that", "the copyright notice and this notice be preserved on all copies" diff --git a/Docs/LICENSE b/Docs/LICENSE deleted file mode 100644 index bd123fe42a5..00000000000 --- a/Docs/LICENSE +++ /dev/null @@ -1,98 +0,0 @@ - End-User License Agreement for MySQL Commercial Server - - (Version 6, July 13, 2000) - - Copyright (C) 2000, MySQL AB & MySQL Finland AB - - Stockholm SWEDEN, Helsingfors FINLAND and Uppsala SWEDEN - - All rights reserved. - -Definitions. This End-User License Agreement ("License") is a legal -agreement between you, either an individual or a single entity, -("Licensee") and MySQL AB, MySQL Finland AB and Detron HB ("Licensor") -for the software product identified above, which includes computer -software and may include associated media, printed materials, and -online or electronic documentation ("Software"). The Software also -includes any updates and supplements to the original Software product -provided to you by Licensor. Any software provided along with the -Software that is associated with a separate end-user license agreement -is licensed to you under the terms of that license agreement. - -Agreement to the License. The Software is protected by copyright laws -and international copyright treaties, as well as other intellectual -property laws and treaties. The Software is licensed, not sold. If you -do not agree to the terms of this License, do not install or use the -Software. By installing, copying, modifying, downloading, -distributing, accessing or otherwise using the Software, you agree to -be bound by the following terms of this License: - -1. Grant for Authorized Use of the Software - -Licensor hereby grants to Licensee a non-exclusive, non-transferable -right to use the Software in: - Installing. You may install copies of -the Software for authorized use on your computers, including -workstations, terminals and other digital electronic devices -("Computer"). - Single Computer use. You may only use the Software on -one Computer at a time regardless the number of Computers with -installed copies. This right covers any number of concurrent users, -CPUs and MySQL-servers with any number of copies running on one -Computer. - -2. Description of Other Rights - -Licensor grants no other rights to the Software except as expressly -set forth herein: - -- Copying. You may not copy the Software unless copies or adaptations - are meant for authorized use, archival purposes or when copying or - adaptation is a necessary step in the authorized use of the Software. - -- Distribution. You may not distribute the Software. - -- Modifying. You may modify the Software but you must reproduce all - copyright notices in the Software on all modified copies and - adaptations. - -- License transfer. You may resell or rent this License. If any - modifications have been made to the Software, you must include a - proper notification that the Software is modified. - -- Support services. Licensor may provide you with support services - related to the Software. Use and terms of support services are not - governed in this License. - -3. Term - -This license is effective until terminated. Licensor has the -right to terminate your License immediately if you fail to comply with -any term of this License. - -4. No Warranty - -The Software is provided "as is". Licensor makes no warranties, -express or implied, arising from course of dealing or usage of trade, -or statutory, as to any matter whatsoever. In particular, any and all -warranties or merchantability, fitness for a particular purpose or -non-infringement of third party rights are expressly excluded. The -entire risk as to the quality and performance of the Software is with -you. If the Software proves defective, you assume all the cost of -necessary service, repair or correction. - -5. Limited Liability - -In no event will Licensor be liable to you for any consequential or -incidental damages, including any lost profits or lost savings, or for -any claim by any party, even if a Licensor representative has been -advised of the possibility of such damages. Some states do not allow -the exclusion or limitation of liability. Therefore, in any case, the -entire liability of Licensor under any provision of this License is -limited to the amount actually paid by you for the Software. - -6. Governing Law and Jurisdiction - -This License will be governed by the laws in force in -Sweden. Jurisdiction is with Tingsrätten of Stockholm, Sweden. - -Should you have any questions concerning the validity of this License, -please contact: mysql-licensing@mysql.com. diff --git a/Docs/MySQLEULA.txt b/Docs/MySQLEULA.txt new file mode 100644 index 00000000000..71e630ec81f --- /dev/null +++ b/Docs/MySQLEULA.txt @@ -0,0 +1,252 @@ + 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://order.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/Docs/manual.texi b/Docs/manual.texi index 45807e95371..c53bd24ac86 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -50797,6 +50797,9 @@ each individual 4.0.x release. @appendixsubsec Changes in release 4.0.5 @itemize @item +Fixed a newly introduced bug that caused @code{ORDER BY ... LIMIT #} +to not return all rows. +@item Fixed a bug in multi-table deletes when outer join is used on an empty table, which get's first to be deleted @item @@ -51589,6 +51592,7 @@ users use this code as the rest of the code and because of this we are not yet 100% confident in this code. @menu +* News-3.23.54:: Changes in release 3.23.54 * News-3.23.53:: Changes in release 3.23.53 * News-3.23.52:: Changes in release 3.23.52 (14 Aug 2002) * News-3.23.51:: Changes in release 3.23.51 (31 May 2002) @@ -51646,12 +51650,45 @@ not yet 100% confident in this code. * News-3.23.0:: Changes in release 3.23.0 (05 Aug 1999: Alpha) @end menu -@node News-3.23.53, News-3.23.52, News-3.23.x, News-3.23.x +@node News-3.23.54, News-3.23.53, News-3.23.x, News-3.23.x +@appendixsubsec Changes in release 3.23.54 +@itemize +@item +Fixed reference to freed memory when doing complicated @code{GROUP BY +... ORDER BY} queries. Symptom was that @code{mysqld} died in function +@code{send_fields}. +@item +Allocate heap rows in smaller blocks to get better memory usage. +@item +Fixed memory allocation bug when storing BLOB values in internal +temporary tables used for some (unlikely) @code{GROUP BY} queries. +@item +Fixed a bug in key optimizing handling where the expression +@code{WHERE column_name = key_column_name} was calculated as true +for @code{NULL} values. +@item +Fixed core dump bug when doing @code{LEFT JOIN ... WHERE key_column=NULL}. +@end itemize + +@node News-3.23.53, News-3.23.52, News-3.23.54, News-3.23.x @appendixsubsec Changes in release 3.23.53 @itemize @bullet @item +Fixed crash when @code{SHOW INNODB STATUS} was used and @code{skip-innodb} +was defined. +@item +Fixed possible memory corruption bug in binary log file handling when +slave rotated the logs (only affected 3.23, not 4.0). +@item +Fixed problem in @code{LOCK TABLES} on windows when one connects to a +database that contains upper case letters. +@item +Fixed that @code{--skip-show-databases} doesn't reset the @code{--port} option. +@item Small fix in @code{safe_mysqld} for some shells. @item +Fixed that @code{FLUSH STATUS} doesn't reset @code{Delayed_insert_threads}. +@item Fixed that @code{SHOW STATUS} doesn't reset @code{Delayed_insert_threads}. @item Fixed core dump bug when using the @code{BINARY} cast on a @code{NULL} value. diff --git a/Docs/world.sql b/Docs/world.sql index 7ddd3787ec6..f253819da2e 100644 --- a/Docs/world.sql +++ b/Docs/world.sql @@ -4334,7 +4334,7 @@ INSERT INTO Country VALUES ('SWZ','Swaziland','Africa','Southern Africa',17364.0 INSERT INTO Country VALUES ('CHE','Switzerland','Europe','Western Europe',41284.00,1499,7160400,79.6,264478.00,256092.00,'Schweiz/Suisse/Svizzera/Svizra','Federation','Adolf Ogi',3248,'CH'); INSERT INTO Country VALUES ('SYR','Syria','Asia','Middle East',185180.00,1941,16125000,68.5,65984.00,64926.00,'Suriya','Republic','Bashar al-Assad',3250,'SY'); INSERT INTO Country VALUES ('TJK','Tajikistan','Asia','Southern and Central Asia',143100.00,1991,6188000,64.1,1990.00,1056.00,'Toçikiston','Republic','Emomali Rahmonov',3261,'TJ'); -INSERT INTO Country VALUES ('TWN','Taiwan, Province of China','Asia','Eastern Asia',36188.00,1945,22256000,76.4,256254.00,263451.00,'T’ai-wan','Republic','Chen Shui-bian',3263,'TW'); +INSERT INTO Country VALUES ('TWN','Taiwan','Asia','Eastern Asia',36188.00,1945,22256000,76.4,256254.00,263451.00,'T’ai-wan','Republic','Chen Shui-bian',3263,'TW'); INSERT INTO Country VALUES ('TZA','Tanzania','Africa','Eastern Africa',883749.00,1961,33517000,52.3,8005.00,7388.00,'Tanzania','Republic','Benjamin William Mkapa',3306,'TZ'); INSERT INTO Country VALUES ('DNK','Denmark','Europe','Nordic Countries',43094.00,800,5330000,76.5,174099.00,169264.00,'Danmark','Constitutional Monarchy','Margrethe II',3315,'DK'); INSERT INTO Country VALUES ('THA','Thailand','Asia','Southeast Asia',513115.00,1350,61399000,68.6,116416.00,153907.00,'Prathet Thai','Constitutional Monarchy','Bhumibol Adulyadej',3320,'TH'); diff --git a/client/mysql.cc b/client/mysql.cc index 0e54a5e1c32..07c1bfeb817 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -628,12 +628,17 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), end_tee(); break; case OPT_PAGER: - opt_nopager= 0; - if (argument) - strmov(pager, argument); + if (argument == disabled_my_option) + opt_nopager= 1; else - strmov(pager, default_pager); - strmov(default_pager, pager); + { + opt_nopager= 0; + if (argument) + strmov(pager, argument); + else + strmov(pager, default_pager); + strmov(default_pager, pager); + } break; case OPT_NOPAGER: printf("WARNING: option deprecated; use --disable-pager instead.\n"); diff --git a/client/mysqladmin.c b/client/mysqladmin.c index 01e36509c30..00af8c592ec 100644 --- a/client/mysqladmin.c +++ b/client/mysqladmin.c @@ -24,7 +24,7 @@ #endif #include <sys/stat.h> -#define ADMIN_VERSION "8.37" +#define ADMIN_VERSION "8.38" #define MAX_MYSQL_VAR 128 #define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */ #define MAX_TRUNC_LENGTH 3 @@ -163,8 +163,8 @@ static struct my_option my_long_options[] = "Print output vertically. Is similar to --relative, but prints output vertically.", (gptr*) &opt_vertical, (gptr*) &opt_vertical, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"wait", 'w', "Wait and retry if connection is down", 0, 0, 0, GET_NO_ARG, - NO_ARG, 0, 0, 0, 0, 0, 0}, + {"wait", 'w', "Wait and retry if connection is down", 0, 0, 0, GET_UINT, + OPT_ARG, 0, 0, 0, 0, 0, 0}, {"connect_timeout", OPT_CONNECT_TIMEOUT, "", (gptr*) &opt_connect_timeout, (gptr*) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 3600*12, 0, 3600*12, 0, 1, 0}, diff --git a/configure.in b/configure.in index e2788a39eb9..f55ed69b348 100644 --- a/configure.in +++ b/configure.in @@ -740,7 +740,7 @@ AC_ARG_WITH(libwrap, _libs=${LIBS} AC_CHECK_HEADER(tcpd.h, - LIBS="$LIBS -lwrap" + LIBS="-lwrap $LIBS" AC_MSG_CHECKING(for TCP wrappers library -lwrap) AC_TRY_LINK([#include <tcpd.h> int allow_severity = 0; diff --git a/heap/heapdef.h b/heap/heapdef.h index c81624059d5..b651bf4bcb1 100644 --- a/heap/heapdef.h +++ b/heap/heapdef.h @@ -23,6 +23,17 @@ #include "heap.h" /* Structs & some defines */ #include "my_tree.h" +/* + When allocating keys /rows in the internal block structure, do it + within the following boundaries. + + The challenge is to find the balance between allocate as few blocks + as possible and keep memory consumption down. +*/ + +#define HP_MIN_RECORDS_IN_BLOCK 16 +#define HP_MAX_RECORDS_IN_BLOCK 8192 + /* Some extern variables */ extern LIST *heap_open_list,*heap_share_list; diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index e35ff2ca69e..3d6b63def6c 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -2531,7 +2531,7 @@ btr_cur_add_path_info( /*********************************************************************** Estimates the number of rows in a given index range. */ -ulint +ib_longlong btr_estimate_n_rows_in_range( /*=========================*/ /* out: estimated number of rows */ @@ -2547,8 +2547,9 @@ btr_estimate_n_rows_in_range( btr_path_t* slot1; btr_path_t* slot2; ibool diverged; + ibool diverged_lot; ulint divergence_level; - ulint n_rows; + ib_longlong n_rows; ulint i; mtr_t mtr; @@ -2589,10 +2590,13 @@ btr_estimate_n_rows_in_range( /* We have the path information for the range in path1 and path2 */ n_rows = 1; - diverged = FALSE; - divergence_level = 1000000; - - for (i = 0; ; i++) { + diverged = FALSE; /* This becomes true when the path is not + the same any more */ + diverged_lot = FALSE; /* This becomes true when the paths are + not the same or adjacent any more */ + divergence_level = 1000000; /* This is the level where paths diverged + a lot */ + for (i = 0; ; i++) { ut_ad(i < BTR_PATH_ARRAY_N_SLOTS); slot1 = path1 + i; @@ -2608,13 +2612,36 @@ btr_estimate_n_rows_in_range( n_rows = n_rows * 2; } + + /* Do not estimate the number of rows in the range + to over 1 / 2 of the estimated rows in the whole + table */ + + if (n_rows > index->table->stat_n_rows / 2) { + n_rows = index->table->stat_n_rows / 2; + + /* If there are just 0 or 1 rows in the table, + then we estimate all rows are in the range */ + + if (n_rows == 0) { + n_rows = index->table->stat_n_rows; + } + } + return(n_rows); } if (!diverged && slot1->nth_rec != slot2->nth_rec) { + diverged = TRUE; + if (slot1->nth_rec < slot2->nth_rec) { n_rows = slot2->nth_rec - slot1->nth_rec; + + if (n_rows > 1) { + diverged_lot = TRUE; + divergence_level = i; + } } else { /* Maybe the tree has changed between searches */ @@ -2622,10 +2649,27 @@ btr_estimate_n_rows_in_range( return(10); } - divergence_level = i; + } else if (diverged && !diverged_lot) { + + if (slot1->nth_rec < slot1->n_recs + || slot2->nth_rec > 1) { + + diverged_lot = TRUE; + divergence_level = i; + + n_rows = 0; + + if (slot1->nth_rec < slot1->n_recs) { + n_rows += slot1->n_recs + - slot1->nth_rec; + } + + if (slot2->nth_rec > 1) { + n_rows += slot2->nth_rec - 1; + } + } + } else if (diverged_lot) { - diverged = TRUE; - } else if (diverged) { n_rows = (n_rows * (slot1->n_recs + slot2->n_recs)) / 2; } diff --git a/innobase/include/btr0cur.h b/innobase/include/btr0cur.h index b01cbd9a875..7039ceba245 100644 --- a/innobase/include/btr0cur.h +++ b/innobase/include/btr0cur.h @@ -417,7 +417,7 @@ btr_cur_parse_del_mark_set_sec_rec( /*********************************************************************** Estimates the number of rows in a given index range. */ -ulint +ib_longlong btr_estimate_n_rows_in_range( /*=========================*/ /* out: estimated number of rows */ diff --git a/innobase/include/os0thread.h b/innobase/include/os0thread.h index 9459750719f..8355afa46e9 100644 --- a/innobase/include/os0thread.h +++ b/innobase/include/os0thread.h @@ -15,7 +15,16 @@ Created 9/8/1995 Heikki Tuuri /* Maximum number of threads which can be created in the program; this is also the size of the wait slot array for MySQL threads which can wait inside InnoDB */ +#ifdef __WIN__ +/* Windows 95/98/ME seemed to have difficulties creating the all +the event semaphores for the wait array slots. If the computer had +<= 64 MB memory, InnoDB startup could take minutes or even crash. +That is why we set this to only 1000 in Windows. */ + +#define OS_THREAD_MAX_N 1000 +#else #define OS_THREAD_MAX_N 10000 +#endif /* Possible fixed priorities for threads */ #define OS_THREAD_PRIORITY_NONE 100 diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index ebd063b6ca5..866fe556af9 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -2011,6 +2011,19 @@ lock_grant( ut_ad(mutex_own(&kernel_mutex)); lock_reset_lock_and_trx_wait(lock); + + if (lock_get_mode(lock) == LOCK_AUTO_INC) { + + if (lock->trx->auto_inc_lock != NULL) { + fprintf(stderr, + "InnoDB: Error: trx already had an AUTO-INC lock!\n"); + } + + /* Store pointer to lock to trx so that we know to + release it at the end of the SQL statement */ + + lock->trx->auto_inc_lock = lock; + } if (lock_print_waits) { printf("Lock wait for trx %lu ends\n", @@ -3763,6 +3776,8 @@ lock_print_info( mtr_t mtr; if (buf_end - buf < 600) { + sprintf(buf, "... output truncated!\n"); + return; } @@ -3787,6 +3802,9 @@ lock_print_info( if ((ulint)(buf_end - buf) < 100 + strlen(lock_latest_err_buf)) { + lock_mutex_exit_kernel(); + sprintf(buf, "... output truncated!\n"); + return; } @@ -3794,6 +3812,9 @@ lock_print_info( } if (buf_end - buf < 600) { + lock_mutex_exit_kernel(); + sprintf(buf, "... output truncated!\n"); + return; } @@ -3805,6 +3826,9 @@ lock_print_info( while (trx) { if (buf_end - buf < 900) { + lock_mutex_exit_kernel(); + sprintf(buf, "... output truncated!\n"); + return; } @@ -3842,6 +3866,9 @@ loop: } if (buf_end - buf < 900) { + lock_mutex_exit_kernel(); + sprintf(buf, "... output truncated!\n"); + return; } @@ -3852,6 +3879,9 @@ loop: buf += strlen(buf); if (buf_end - buf < 500) { + lock_mutex_exit_kernel(); + sprintf(buf, "... output truncated!\n"); + return; } @@ -3906,6 +3936,9 @@ loop: } if (buf_end - buf < 500) { + lock_mutex_exit_kernel(); + sprintf(buf, "... output truncated!\n"); + return; } diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index b2881581fc7..098d5b25e89 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -1034,6 +1034,8 @@ try_again: ibool retry; ssize_t ret; + os_bytes_read_since_printout += n; + try_again: ret = os_file_pread(file, buf, n, offset, offset_high); diff --git a/innobase/os/os0thread.c b/innobase/os/os0thread.c index 146303b2791..48aea4b8abb 100644 --- a/innobase/os/os0thread.c +++ b/innobase/os/os0thread.c @@ -52,8 +52,8 @@ os_thread_pf( /*=========*/ os_thread_id_t a) { -#ifdef UNIV_HPUX - /* In HP-UX a pthread_t is a struct of 3 fields: field1, field2, +#ifdef UNIV_HPUX10 + /* In HP-UX-10.20 a pthread_t is a struct of 3 fields: field1, field2, field3. We do not know if field1 determines the thread uniquely. */ return((ulint)(a.field1)); diff --git a/libmysqld/examples/builder-sample/emb_sample.bpr b/libmysqld/examples/builder-sample/emb_sample.bpr new file mode 100644 index 00000000000..07b39a6832b --- /dev/null +++ b/libmysqld/examples/builder-sample/emb_sample.bpr @@ -0,0 +1,192 @@ +# --------------------------------------------------------------------------- +!if !$d(BCB) +BCB = $(MAKEDIR)\.. +!endif + +# --------------------------------------------------------------------------- +# IDE SECTION +# --------------------------------------------------------------------------- +# The following section of the project makefile is managed by the BCB IDE. +# It is recommended to use the IDE to change any of the values in this +# section. +# --------------------------------------------------------------------------- + +VERSION = BCB.04.04 +# --------------------------------------------------------------------------- +PROJECT = emb_sample.exe +OBJFILES = emb_sample.obj emb_samples.obj +RESFILES = emb_sample.res +RESDEPEN = $(RESFILES) emb_samples.dfm +LIBFILES = libmysqld.lib +LIBRARIES = +SPARELIBS = Vcl40.lib +PACKAGES = Vcl40.bpi Vclx40.bpi vcljpg40.bpi bcbsmp40.bpi Qrpt40.bpi Vcldb40.bpi \ + ibsmp40.bpi vcldbx40.bpi TeeUI40.bpi teedb40.bpi tee40.bpi nmfast40.bpi \ + dclocx40.bpi +DEFFILE = +# --------------------------------------------------------------------------- +PATHCPP = .; +PATHASM = .; +PATHPAS = .; +PATHRC = .; +DEBUGLIBPATH = $(BCB)\lib\debug +RELEASELIBPATH = $(BCB)\lib\release +USERDEFINES = +SYSDEFINES = _RTLDLL;NO_STRICT;USEPACKAGES +# --------------------------------------------------------------------------- +CFLAG1 = -I$(BCB)\include;$(BCB)\include\vcl;..\..\..\include -Od -Hc \ + -H=$(BCB)\lib\vcl40.csm -w -Ve -r- -a8 -k -y -v -vi- -c -b- -w-par -w-inl -Vx \ + -tW -tWM -D$(SYSDEFINES);$(USERDEFINES) +PFLAGS = -U$(BCB)\lib\obj;$(BCB)\lib;$(RELEASELIBPATH) \ + -I$(BCB)\include;$(BCB)\include\vcl;..\..\..\include -$YD -$W -$O- -v -JPHNE -M +RFLAGS = -i$(BCB)\include;$(BCB)\include\vcl;..\..\..\include +AFLAGS = /i$(BCB)\include /i$(BCB)\include\vcl /i..\..\..\include /mx /w2 /zd +LFLAGS = -L$(BCB)\lib\obj;$(BCB)\lib;$(RELEASELIBPATH) -aa -Tpe -x -Gn -v +# --------------------------------------------------------------------------- +ALLOBJ = c0w32.obj Memmgr.Lib $(PACKAGES) sysinit.obj $(OBJFILES) +ALLRES = $(RESFILES) +ALLLIB = $(LIBFILES) $(LIBRARIES) import32.lib cp32mti.lib +# --------------------------------------------------------------------------- +!ifdef IDEOPTIONS + +[Version Info] +IncludeVerInfo=1 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1046 +CodePage=1252 + +[Version Info Keys] +CompanyName=MySQL AB +FileDescription=Embedded Server Sample +FileVersion=1.0.0.0 +InternalName=Builder Embedded Server Sample +LegalCopyright=GNU +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= + +[HistoryLists\hlIncludePath] +Count=2 +Item0=$(BCB)\include;$(BCB)\include\vcl;..\..\..\include +Item1=$(BCB)\include;$(BCB)\include\vcl;..\..\..\inluce + +[HistoryLists\hlLibraryPath] +Count=1 +Item0=$(BCB)\lib\obj;$(BCB)\lib + +[HistoryLists\hlDebugSourcePath] +Count=1 +Item0=$(BCB)\source\vcl + +[Debugging] +DebugSourceDirs=$(BCB)\source\vcl + +[Parameters] +RunParams= +HostApplication= +RemoteHost= +RemotePath= +RemoteDebug=0 + +[Compiler] +InMemoryExe=0 +ShowInfoMsgs=0 + +!endif + +# --------------------------------------------------------------------------- +# MAKE SECTION +# --------------------------------------------------------------------------- +# This section of the project file is not used by the BCB IDE. It is for +# the benefit of building from the command-line using the MAKE utility. +# --------------------------------------------------------------------------- + +.autodepend +# --------------------------------------------------------------------------- +!if !$d(BCC32) +BCC32 = bcc32 +!endif + +!if !$d(CPP32) +CPP32 = cpp32 +!endif + +!if !$d(DCC32) +DCC32 = dcc32 +!endif + +!if !$d(TASM32) +TASM32 = tasm32 +!endif + +!if !$d(LINKER) +LINKER = ilink32 +!endif + +!if !$d(BRCC32) +BRCC32 = brcc32 +!endif + +# --------------------------------------------------------------------------- +!if $d(PATHCPP) +.PATH.CPP = $(PATHCPP) +.PATH.C = $(PATHCPP) +!endif + +!if $d(PATHPAS) +.PATH.PAS = $(PATHPAS) +!endif + +!if $d(PATHASM) +.PATH.ASM = $(PATHASM) +!endif + +!if $d(PATHRC) +.PATH.RC = $(PATHRC) +!endif +# --------------------------------------------------------------------------- +$(PROJECT): $(OBJFILES) $(RESDEPEN) $(DEFFILE) + $(BCB)\BIN\$(LINKER) @&&! + $(LFLAGS) + + $(ALLOBJ), + + $(PROJECT),, + + $(ALLLIB), + + $(DEFFILE), + + $(ALLRES) +! +# --------------------------------------------------------------------------- +.pas.hpp: + $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } + +.pas.obj: + $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } + +.cpp.obj: + $(BCB)\BIN\$(BCC32) $(CFLAG1) -n$(@D) {$< } + +.c.obj: + $(BCB)\BIN\$(BCC32) $(CFLAG1) -n$(@D) {$< } + +.c.i: + $(BCB)\BIN\$(CPP32) $(CFLAG1) -n. {$< } + +.cpp.i: + $(BCB)\BIN\$(CPP32) $(CFLAG1) -n. {$< } + +.asm.obj: + $(BCB)\BIN\$(TASM32) $(AFLAGS) $<, $@ + +.rc.res: + $(BCB)\BIN\$(BRCC32) $(RFLAGS) -fo$@ $< +# --------------------------------------------------------------------------- diff --git a/libmysqld/examples/builder-sample/emb_sample.cpp b/libmysqld/examples/builder-sample/emb_sample.cpp new file mode 100644 index 00000000000..5ad3bd69319 --- /dev/null +++ b/libmysqld/examples/builder-sample/emb_sample.cpp @@ -0,0 +1,23 @@ +//--------------------------------------------------------------------------- +#include <vcl.h> +#pragma hdrstop +USERES("emb_sample.res"); +USEFORM("emb_samples.cpp", Form1); +USELIB("libmysqld.lib"); +//--------------------------------------------------------------------------- +WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) +{ + try + { + Application->Initialize(); + Application->Title = "MySQL Embedded Server Sample"; + Application->CreateForm(__classid(TForm1), &Form1); + Application->Run(); + } + catch (Exception &exception) + { + Application->ShowException(&exception); + } + return 0; +} +//--------------------------------------------------------------------------- diff --git a/libmysqld/examples/builder-sample/emb_sample.tds b/libmysqld/examples/builder-sample/emb_sample.tds Binary files differnew file mode 100644 index 00000000000..2471b6c112f --- /dev/null +++ b/libmysqld/examples/builder-sample/emb_sample.tds diff --git a/libmysqld/examples/builder-sample/emb_samples.cpp b/libmysqld/examples/builder-sample/emb_samples.cpp new file mode 100644 index 00000000000..4dfde111f84 --- /dev/null +++ b/libmysqld/examples/builder-sample/emb_samples.cpp @@ -0,0 +1,283 @@ +//--------------------------------------------------------------------------- +#include <vcl.h> +#pragma hdrstop + +#include "emb_samples.h" +#include <winsock.h> +#include <mysql.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <deque.h> +bool b_new_line = false; +const char *server_groups[] = { + "", "embedded", "server", NULL +}; +MYSQL *MySQL; +deque<string> fill_rows(MYSQL_RES *res); +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TForm1 *Form1; +//--------------------------------------------------------------------------- +deque<string> fill_rows(MYSQL_RES *res) +{ + MYSQL_ROW row; + deque<string> rows; + + while ((row=mysql_fetch_row(res)) != 0) + { + mysql_field_seek(res,0); + for (unsigned int i=0 ; i < mysql_num_fields(res); i++) + rows.push_back(row[i]); + } + return rows; +} +//--------------------------------------------------------------------------- +__fastcall TForm1::TForm1(TComponent* Owner) + : TForm(Owner) +{ +} +//--------------------------------------------------------------------------- + +void __fastcall TForm1::Timer1Timer(TObject *Sender) +{ + if (is_server_started) + { + ToggleButton->Caption = "Quit"; + Timer1->Enabled = false; + } +} +//--------------------------------------------------------------------------- +void __fastcall TForm1::FormCreate(TObject *Sender) +{ + is_server_started = false; + computer_ip(); /* get the computer name and IP number */ + /* init the tree database screen */ + db_root = DBView->Items->Add(NULL, db_root_caption.UpperCase()); + db_root->ImageIndex = 0; +} +//--------------------------------------------------------------------------- +/* button which handle the init of mysql server or quit the app */ +void __fastcall TForm1::ToggleButtonClick(TObject *Sender) +{ + if (!is_server_started) + { + mysql_server_init(NULL, NULL, (char **)server_groups) ; + connect_server(); + get_dbs(); + } + else + { + mysql_server_end(); + Close(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TForm1::computer_ip(void) +{ + WORD wVersionRequested; + WSADATA WSAData; + wVersionRequested = MAKEWORD(1,1); + WSAStartup(wVersionRequested,&WSAData); + hostent *P; + char s[128]; + in_addr in; + char *P2; + + gethostname(s, 128); + P = gethostbyname(s); + db_root_caption = P->h_name; + in.S_un.S_un_b.s_b1 = P->h_addr_list[0][0]; + in.S_un.S_un_b.s_b2 = P->h_addr_list[0][1]; + in.S_un.S_un_b.s_b3 = P->h_addr_list[0][2]; + in.S_un.S_un_b.s_b4 = P->h_addr_list[0][3]; + P2 = inet_ntoa(in); + db_root_caption += " ( " + (AnsiString)P2 + " )"; +} +//--------------------------------------------------------------------------- +bool __fastcall TForm1::connect_server() +{ + bool ret_value = false; + + MySQL = mysql_init(MySQL); + if (!MySQL) + return ret_value; + if (mysql_real_connect(MySQL, NULL, NULL, NULL, NULL, 0, NULL, 0)) + { + ret_value = true; + is_server_started = true; + } + return ret_value; +} +//--------------------------------------------------------------------------- +void __fastcall TForm1::FormDestroy(TObject *Sender) +{ + if (is_server_started) + mysql_server_end(); +} +//--------------------------------------------------------------------------- + +void __fastcall TForm1::DBViewClick(TObject *Sender) +{ + if (DBView->Selected != db_root && DBView->Selected != NULL) + { + get_tables(DBView->Selected->Text); + clean_desc_grid(); + } +} +//--------------------------------------------------------------------------- +bool __fastcall TForm1::get_tables(String db_name) +{ + MYSQL_RES *res; + AnsiString s_cmd; + + TableView->Items->Clear(); + s_cmd = "use "; + s_cmd+= db_name.c_str(); + + if (mysql_query(MySQL, s_cmd.c_str()) || + !(res=mysql_list_tables(MySQL,"%"))) + return false; + + tables_node = TableView->Items->Add(NULL, db_name.c_str()); + tables_node->ImageIndex = 1; + tables_node->SelectedIndex = 1; + + deque<string> rows = fill_rows(res); + + mysql_free_result(res); + fill_tree(rows,tables_tree,tables_node,TableView,2); + + return true; +} +//--------------------------------------------------------------------------- +bool __fastcall TForm1::get_dbs(void) +{ + MYSQL_RES *res; + + if (!is_server_started) + return false; + + if (!(res=mysql_list_dbs(MySQL,"%"))) + return false; + + deque<string> rows = fill_rows(res); + + mysql_free_result(res); + fill_tree(rows,MySQLDbs,db_root,DBView,1); + info_server->Text = mysql_get_server_info(MySQL); + + return true; +} +//--------------------------------------------------------------------------- +void __fastcall TForm1::fill_tree(deque<string> rows, + TTreeNode *root, + TTreeNode *child, + TTreeView *View, + int image_index) +{ + deque<string>::iterator r; + for(r = rows.begin(); r != rows.end() ; r++) + { + root = View->Items->AddChild(child, (*r).c_str()); + root->ImageIndex = image_index; + root->SelectedIndex = image_index; + } + child->Expanded = true; +} +//--------------------------------------------------------------------------- +bool __fastcall TForm1::get_desc_table(String table_name) +{ + MYSQL_RES *res, *res1; + MYSQL_ROW row; + AnsiString use_db, show_cols, show_desc; + unsigned int num_fields; + int fields_control = 0, grid_row = 1, fields_number; + b_new_line= true; + + clean_desc_grid(); + use_db = "use "; + use_db+= DBView->Selected->Text.c_str(); + show_desc = "desc "; + show_cols = "show full columns from "; + show_cols+= table_name.c_str(); + show_desc+= table_name.c_str(); + + if (mysql_query(MySQL, use_db.c_str() )) + return false; + + if (mysql_query(MySQL, show_cols.c_str() ) || + !(res1=mysql_store_result(MySQL))) + { + if (mysql_query(MySQL, show_desc.c_str() ) || + !(res1=mysql_store_result(MySQL))) + return false ; + } + mysql_fetch_row(res1); + mysql_field_seek(res1,0); + fields_number = (mysql_num_fields(res1) - 2); + mysql_free_result(res1); + + if (mysql_query(MySQL, show_cols.c_str() ) || + !(res=mysql_store_result(MySQL))) + { + if (mysql_query(MySQL, show_desc.c_str() ) || + !(res=mysql_store_result(MySQL))) + return false ; + } + titles_grid(); + while ((row=mysql_fetch_row(res)) != 0) + { + mysql_field_seek(res,0); + for (num_fields=0 ; num_fields < mysql_num_fields(res); num_fields++) + { + if (fields_control <= fields_number ) + { + desc_table_grid->Cells[fields_control][grid_row] = row[num_fields]; + fields_control++; + } + else + { + desc_table_grid->Cells[(fields_control)][grid_row] = row[num_fields]; + fields_control = 0; + grid_row++ ; + desc_table_grid->RowCount++; + } + } + } + desc_table_grid->RowCount--; + mysql_free_result(res); + return true; +} +//--------------------------------------------------------------------------- +void __fastcall TForm1::TableViewClick(TObject *Sender) +{ + if (DBView->Selected != db_root && DBView->Selected != NULL) + if (DBView->Selected != tables_tree) + get_desc_table(TableView->Selected->Text); +} +//--------------------------------------------------------------------------- +void __fastcall TForm1::clean_desc_grid(void) +{ + desc_table_grid->RowCount= 2; + desc_table_grid->Cells[0][1] = ""; + desc_table_grid->Cells[1][1] = ""; + desc_table_grid->Cells[2][1] = ""; + desc_table_grid->Cells[3][1] = ""; + desc_table_grid->Cells[4][1] = ""; + desc_table_grid->Cells[5][1] = ""; +} +//--------------------------------------------------------------------------- +void __fastcall TForm1::titles_grid(void) +{ + desc_table_grid->Cells[0][0] = "Field"; + desc_table_grid->Cells[1][0] = "Type"; + desc_table_grid->Cells[2][0] = "Null"; + desc_table_grid->Cells[3][0] = "Key"; + desc_table_grid->Cells[4][0] = "Default"; + desc_table_grid->Cells[5][0] = "Extra"; + desc_table_grid->Cells[6][0] = "Privileges"; +} + diff --git a/libmysqld/examples/builder-sample/emb_samples.dfm b/libmysqld/examples/builder-sample/emb_samples.dfm Binary files differnew file mode 100644 index 00000000000..399509eeb8e --- /dev/null +++ b/libmysqld/examples/builder-sample/emb_samples.dfm diff --git a/libmysqld/examples/builder-sample/emb_samples.h b/libmysqld/examples/builder-sample/emb_samples.h new file mode 100644 index 00000000000..0562bc783cd --- /dev/null +++ b/libmysqld/examples/builder-sample/emb_samples.h @@ -0,0 +1,61 @@ +//--------------------------------------------------------------------------- +#ifndef emb_samplesH +#define emb_samplesH +//--------------------------------------------------------------------------- +#include <Classes.hpp> +#include <Controls.hpp> +#include <StdCtrls.hpp> +#include <Forms.hpp> +#include <ComCtrls.hpp> +#include <Grids.hpp> +#include <ImgList.hpp> +#include <ExtCtrls.hpp> +#include <Graphics.hpp> +#include <Buttons.hpp> +#include <deque.h> +//--------------------------------------------------------------------------- +class TForm1 : public TForm +{ +__published: // IDE-managed Components + TGroupBox *GroupBox1; + TTreeView *DBView; + TTreeView *TableView; + TStringGrid *desc_table_grid; + TImageList *ImageList2; + TStatusBar *StatusBar1; + TImage *Image1; + TBitBtn *ToggleButton; + TTimer *Timer1; + TLabel *Label1; + TEdit *info_server; + TLabel *Label2; + void __fastcall Timer1Timer(TObject *Sender); + void __fastcall FormCreate(TObject *Sender); + void __fastcall ToggleButtonClick(TObject *Sender); + void __fastcall FormDestroy(TObject *Sender); + void __fastcall DBViewClick(TObject *Sender); + void __fastcall TableViewClick(TObject *Sender); +private: // User declarations +public: // User declarations + bool is_server_started; + AnsiString db_root_caption; + TTreeNode *db_root, *MySQLDbs, *tables_node, *tables_tree; + void __fastcall computer_ip(void); + bool __fastcall get_dbs(void); + bool __fastcall get_tables(String db_name); + bool __fastcall get_desc_table(String table_name); + bool __fastcall connect_server(); + void __fastcall clean_desc_grid(void); + void __fastcall titles_grid(void); + void __fastcall fill_tree(deque<string> rows, + TTreeNode *root, + TTreeNode *child, + TTreeView *View, + int image_index); + + __fastcall TForm1(TComponent* Owner); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TForm1 *Form1; +//--------------------------------------------------------------------------- +#endif diff --git a/libmysqld/examples/builder-sample/images/db.ico b/libmysqld/examples/builder-sample/images/db.ico Binary files differnew file mode 100644 index 00000000000..ca749002acc --- /dev/null +++ b/libmysqld/examples/builder-sample/images/db.ico diff --git a/libmysqld/examples/builder-sample/images/find.ico b/libmysqld/examples/builder-sample/images/find.ico Binary files differnew file mode 100644 index 00000000000..2e0f96c52f9 --- /dev/null +++ b/libmysqld/examples/builder-sample/images/find.ico diff --git a/libmysqld/examples/builder-sample/images/logo.ico b/libmysqld/examples/builder-sample/images/logo.ico Binary files differnew file mode 100644 index 00000000000..9409cad72b6 --- /dev/null +++ b/libmysqld/examples/builder-sample/images/logo.ico diff --git a/libmysqld/examples/builder-sample/images/mysql.bmp b/libmysqld/examples/builder-sample/images/mysql.bmp Binary files differnew file mode 100644 index 00000000000..ed5c7f9051f --- /dev/null +++ b/libmysqld/examples/builder-sample/images/mysql.bmp diff --git a/libmysqld/examples/builder-sample/images/net.ico b/libmysqld/examples/builder-sample/images/net.ico Binary files differnew file mode 100644 index 00000000000..bb11e34bd1d --- /dev/null +++ b/libmysqld/examples/builder-sample/images/net.ico diff --git a/libmysqld/examples/builder-sample/libmysqld.lib b/libmysqld/examples/builder-sample/libmysqld.lib Binary files differnew file mode 100644 index 00000000000..994e67e675e --- /dev/null +++ b/libmysqld/examples/builder-sample/libmysqld.lib diff --git a/libmysqld/examples/builder-sample/snapshot.jpg b/libmysqld/examples/builder-sample/snapshot.jpg Binary files differnew file mode 100644 index 00000000000..b132fac8376 --- /dev/null +++ b/libmysqld/examples/builder-sample/snapshot.jpg diff --git a/myisam/mi_open.c b/myisam/mi_open.c index cd11f190d24..e4e70f649a4 100644 --- a/myisam/mi_open.c +++ b/myisam/mi_open.c @@ -215,7 +215,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) max_data_file_length= (share->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? (((ulonglong) 1 << (share->base.rec_reflength*8))-1) : - (mi_safe_mul(share->base.reclength, + (mi_safe_mul(share->base.pack_reclength, (ulonglong) 1 << (share->base.rec_reflength*8))-1); max_key_file_length= mi_safe_mul(MI_MIN_KEY_BLOCK_LENGTH, diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result index 227b34f3691..057e0308313 100644 --- a/mysql-test/r/distinct.result +++ b/mysql-test/r/distinct.result @@ -190,7 +190,7 @@ insert into t3 select * from t4; explain select distinct t1.a from t1,t3 where t1.a=t3.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 2 Using index; Using temporary -1 SIMPLE t3 ref a a 5 t1.a 10 Using index; Distinct +1 SIMPLE t3 ref a a 5 t1.a 10 where used; Using index; Distinct select distinct t1.a from t1,t3 where t1.a=t3.a; a 1 diff --git a/mysql-test/r/null_key.result b/mysql-test/r/null_key.result index 0a708ff298c..c6aed00b6c5 100644 --- a/mysql-test/r/null_key.result +++ b/mysql-test/r/null_key.result @@ -188,4 +188,10 @@ id uniq_id 4 2 7 3 8 4 +order_id product_id product_type +order_id product_id product_type +3d7ce39b5d4b3e3d22aaafe9b633de51 1206029 3 +3d7ce39b5d4b3e3d22aaafe9b633de51 5880836 3 +id id +id id DROP table t1,t2; diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index fc918012d1f..925f754f203 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -3266,3 +3266,205 @@ select wss_type from t1 where wss_type =102935229216544093; wss_type 102935229216544093 drop table t1; +create table t1 (a int not null auto_increment primary key); +insert into t1 values (); +insert into t1 values (); +insert into t1 values (); +select * from (t1 as t2 left join t1 as t3 using (a)), t1; +a a a +1 1 1 +2 2 1 +3 3 1 +1 1 2 +2 2 2 +3 3 2 +1 1 3 +2 2 3 +3 3 3 +select * from t1, (t1 as t2 left join t1 as t3 using (a)); +a a a +1 1 1 +2 1 1 +3 1 1 +1 2 2 +2 2 2 +3 2 2 +1 3 3 +2 3 3 +3 3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) straight_join t1; +a a a +1 1 1 +2 2 1 +3 3 1 +1 1 2 +2 2 2 +3 3 2 +1 1 3 +2 2 3 +3 3 3 +select * from t1 straight_join (t1 as t2 left join t1 as t3 using (a)); +a a a +1 1 1 +2 1 1 +3 1 1 +1 2 2 +2 2 2 +3 2 2 +1 3 3 +2 3 3 +3 3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) inner join t1 on t1.a>1; +a a a +1 1 2 +2 2 2 +3 3 2 +1 1 3 +2 2 3 +3 3 3 +select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; +a a a +1 1 NULL +2 1 1 +3 1 1 +1 2 NULL +2 2 2 +3 2 2 +1 3 NULL +2 3 3 +3 3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) inner join t1 using ( a ); +a a a +1 1 1 +2 2 2 +3 3 3 +select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) using ( a ); +a a a +1 1 1 +2 1 NULL +3 1 NULL +1 2 NULL +2 2 2 +3 2 NULL +1 3 NULL +2 3 NULL +3 3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) left outer join t1 on t1.a>1; +a a a +1 1 2 +1 1 3 +2 2 2 +2 2 3 +3 3 2 +3 3 3 +select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; +a a a +1 1 NULL +2 1 1 +3 1 1 +1 2 NULL +2 2 2 +3 2 2 +1 3 NULL +2 3 3 +3 3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) left join t1 using ( a ); +a a a +1 1 1 +2 2 2 +3 3 3 +select * from t1 left join (t1 as t2 left join t1 as t3 using (a)) using ( a ); +a a a +1 1 1 +2 1 NULL +3 1 NULL +1 2 NULL +2 2 2 +3 2 NULL +1 3 NULL +2 3 NULL +3 3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1; +a a a +1 1 1 +2 2 2 +3 3 3 +select * from t1 natural left join (t1 as t2 left join t1 as t3 using (a)); +a a a +1 1 1 +2 1 NULL +3 1 NULL +1 2 NULL +2 2 2 +3 2 NULL +1 3 NULL +2 3 NULL +3 3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) right join t1 on t1.a>1; +a a a +1 NULL 1 +2 NULL 1 +3 NULL 1 +1 1 2 +2 2 2 +3 3 2 +1 1 3 +2 2 3 +3 3 3 +select * from t1 right join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; +a a a +2 1 1 +3 1 1 +2 2 2 +3 2 2 +2 3 3 +3 3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) right outer join t1 using ( a ); +a a a +1 1 1 +2 NULL 1 +3 NULL 1 +1 NULL 2 +2 2 2 +3 NULL 2 +1 NULL 3 +2 NULL 3 +3 3 3 +select * from t1 right outer join (t1 as t2 left join t1 as t3 using (a)) using ( a ); +a a a +1 1 1 +2 2 2 +3 3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) natural right join t1; +a a a +1 1 1 +2 NULL 1 +3 NULL 1 +1 NULL 2 +2 2 2 +3 NULL 2 +1 NULL 3 +2 NULL 3 +3 3 3 +select * from t1 natural right join (t1 as t2 left join t1 as t3 using (a)); +a a a +1 1 1 +2 2 2 +3 3 3 +select * from t1 natural join (t1 as t2 left join t1 as t3 using (a)); +a a a +1 1 1 +2 1 NULL +3 1 NULL +1 2 NULL +2 2 2 +3 2 NULL +1 3 NULL +2 3 NULL +3 3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) natural join t1; +a a a +1 1 1 +2 2 2 +3 3 3 +drop table t1; diff --git a/mysql-test/t/null_key.test b/mysql-test/t/null_key.test index e5d8fc59e4f..3ab8b993f43 100644 --- a/mysql-test/t/null_key.test +++ b/mysql-test/t/null_key.test @@ -91,3 +91,47 @@ DELETE FROM t2 WHERE uniq_id IS NULL; SELECT * FROM t1 ORDER BY uniq_id, id; SELECT * FROM t2 ORDER BY uniq_id, id; DROP table t1,t2; + +# +# This crashed MySQL 3.23.47 +# + +CREATE TABLE `t1` ( + `order_id` char(32) NOT NULL default '', + `product_id` char(32) NOT NULL default '', + `product_type` int(11) NOT NULL default '0', + PRIMARY KEY (`order_id`,`product_id`,`product_type`) +) TYPE=MyISAM; +CREATE TABLE `t2` ( + `order_id` char(32) NOT NULL default '', + `product_id` char(32) NOT NULL default '', + `product_type` int(11) NOT NULL default '0', + PRIMARY KEY (`order_id`,`product_id`,`product_type`) +) TYPE=MyISAM; +INSERT INTO t1 (order_id, product_id, product_type) VALUES +('3d7ce39b5d4b3e3d22aaafe9b633de51',1206029, 3), +('3d7ce39b5d4b3e3d22aaafe9b633de51',5880836, 3), +('9d9aad7764b5b2c53004348ef8d34500',2315652, 3); +INSERT INTO t2 (order_id, product_id, product_type) VALUES +('9d9aad7764b5b2c53004348ef8d34500',2315652, 3); + +select t1.* from t1 +left join t2 using(order_id, product_id, product_type) +where t2.order_id=NULL; +select t1.* from t1 +left join t2 using(order_id, product_id, product_type) +where t2.order_id is NULL; +drop table t1,t2; + +# +# The last select returned wrong results in 3.23.52 +# + +create table t1 (id int); +insert into t1 values (null), (0); +create table t2 (id int); +insert into t2 values (null); +select * from t1, t2 where t1.id = t2.id; +alter table t1 add key id (id); +select * from t1, t2 where t1.id = t2.id; +drop table t1,t2; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 94806d44e37..15d44bcd672 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -1751,3 +1751,49 @@ select wss_type from t1 where wss_type ='102935229216544104'; select wss_type from t1 where wss_type ='102935229216544093'; select wss_type from t1 where wss_type =102935229216544093; drop table t1; + +# +# Test of removing redundant braces in the FROM part +# (We test each construct with the braced join to the left and right; +# the latter case used to cause a syntax errors.) +# + +create table t1 (a int not null auto_increment primary key); +insert into t1 values (); +insert into t1 values (); +insert into t1 values (); +# , +select * from (t1 as t2 left join t1 as t3 using (a)), t1; +select * from t1, (t1 as t2 left join t1 as t3 using (a)); +# stright_join +select * from (t1 as t2 left join t1 as t3 using (a)) straight_join t1; +select * from t1 straight_join (t1 as t2 left join t1 as t3 using (a)); +# inner join on +select * from (t1 as t2 left join t1 as t3 using (a)) inner join t1 on t1.a>1; +select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; +# inner join using +select * from (t1 as t2 left join t1 as t3 using (a)) inner join t1 using ( a ); +select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) using ( a ); +# left [outer] join on +select * from (t1 as t2 left join t1 as t3 using (a)) left outer join t1 on t1.a>1; +select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; +# left join using +select * from (t1 as t2 left join t1 as t3 using (a)) left join t1 using ( a ); +select * from t1 left join (t1 as t2 left join t1 as t3 using (a)) using ( a ); +# natural left join +select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1; +select * from t1 natural left join (t1 as t2 left join t1 as t3 using (a)); +# right join on +select * from (t1 as t2 left join t1 as t3 using (a)) right join t1 on t1.a>1; +select * from t1 right join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; +# right [outer] joing using +select * from (t1 as t2 left join t1 as t3 using (a)) right outer join t1 using ( a ); +select * from t1 right outer join (t1 as t2 left join t1 as t3 using (a)) using ( a ); +# natural right join +select * from (t1 as t2 left join t1 as t3 using (a)) natural right join t1; +select * from t1 natural right join (t1 as t2 left join t1 as t3 using (a)); +# natural join +select * from t1 natural join (t1 as t2 left join t1 as t3 using (a)); +select * from (t1 as t2 left join t1 as t3 using (a)) natural join t1; + +drop table t1; diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 494e7ac559c..b2ee6e0f373 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -634,31 +634,38 @@ static void init_variables(const struct my_option *options) { switch (options->var_type) { case GET_BOOL: - *((my_bool*) options->u_max_value)= (my_bool) options->max_value; + if (options->u_max_value) + *((my_bool*) options->u_max_value)= (my_bool) options->max_value; *((my_bool*) options->value)= (my_bool) options->def_value; break; case GET_INT: - *((int*) options->u_max_value)= (int) options->max_value; + if (options->u_max_value) + *((int*) options->u_max_value)= (int) options->max_value; *((int*) options->value)= (int) options->def_value; break; case GET_UINT: - *((uint*) options->u_max_value)= (uint) options->max_value; + if (options->u_max_value) + *((uint*) options->u_max_value)= (uint) options->max_value; *((uint*) options->value)= (uint) options->def_value; break; case GET_LONG: - *((long*) options->u_max_value)= (long) options->max_value; + if (options->u_max_value) + *((long*) options->u_max_value)= (long) options->max_value; *((long*) options->value)= (long) options->def_value; break; case GET_ULONG: - *((ulong*) options->u_max_value)= (ulong) options->max_value; + if (options->u_max_value) + *((ulong*) options->u_max_value)= (ulong) options->max_value; *((ulong*) options->value)= (ulong) options->def_value; break; case GET_LL: - *((longlong*) options->u_max_value)= (longlong) options->max_value; + if (options->u_max_value) + *((longlong*) options->u_max_value)= (longlong) options->max_value; *((longlong*) options->value)= (longlong) options->def_value; break; case GET_ULL: - *((ulonglong*) options->u_max_value)= (ulonglong) options->max_value; + if (options->u_max_value) + *((ulonglong*) options->u_max_value)= (ulonglong) options->max_value; *((ulonglong*) options->value)= (ulonglong) options->def_value; break; default: /* dummy default to avoid compiler warnings */ diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index 2b990448b08..89079fba31c 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -201,9 +201,7 @@ gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags) pthread_mutex_unlock(&THR_LOCK_malloc); /* Set the memory to the aribtrary wierd value */ -#ifdef HAVE_purify - if (MyFlags & MY_ZEROFILL) -#endif + if ((MyFlags & MY_ZEROFILL) || !sf_malloc_quick) bfill(&pTmp -> aData[sf_malloc_prehunc],uSize, (char) (MyFlags & MY_ZEROFILL ? 0 : ALLOC_VAL)); /* Return a pointer to the real data */ @@ -321,7 +319,8 @@ void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags) #ifndef HAVE_purify /* Mark this data as free'ed */ - bfill(&pRec->aData[sf_malloc_prehunc],pRec->uDataSize,(pchar) FREE_VAL); + if (!sf_malloc_quick) + bfill(&pRec->aData[sf_malloc_prehunc],pRec->uDataSize,(pchar) FREE_VAL); #endif *((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc)) = ~MAGICKEY; diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index e5d7f20c6df..9d25943bb52 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -55,7 +55,7 @@ mkdir $BASE $BASE/bin $BASE/data $BASE/data/mysql $BASE/data/test \ chmod o-rwx $BASE/data $BASE/data/* for i in ChangeLog COPYING COPYING.LIB README Docs/INSTALL-BINARY \ - LICENSE Docs/manual.html Docs/manual.txt Docs/manual_toc.html + MySQLEULA.txt Docs/manual.html Docs/manual.txt Docs/manual_toc.html do if [ -f $i ] then diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh index 1aad5c95c25..d808ffdcaef 100644 --- a/scripts/mysqlhotcopy.sh +++ b/scripts/mysqlhotcopy.sh @@ -37,7 +37,7 @@ WARNING: THIS PROGRAM IS STILL IN BETA. Comments/patches welcome. # Documentation continued at end of file -my $VERSION = "1.16"; +my $VERSION = "1.17"; my $opt_tmpdir = $ENV{TMPDIR} || "/tmp"; @@ -388,6 +388,8 @@ foreach my $rdb ( @db_desc ) { foreach my $td ( '', @{$rdb->{raid_dirs}} ) { my $tgt_dirpath = "$rdb->{target}/$td"; + # Remove trailing slashes (needed for Mac OS X) + substr($tgt_dirpath, 1) =~ s|/+$||; if ( $opt{dryrun} ) { print "mkdir $tgt_dirpath, 0750\n"; } @@ -1001,3 +1003,5 @@ resulted in nothing being copied when a regexp was specified but no database name(s). Martin Waite - Fix to handle database name that contains space. + +Paul DuBois - Remove end '/' from directory names diff --git a/sql/field.h b/sql/field.h index d8cfba14e02..a1a511075fb 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1094,6 +1094,7 @@ Field *make_field(char *ptr, uint32 field_length, uint pack_length_to_packflag(uint type); uint32 calc_pack_length(enum_field_types type,uint32 length); bool set_field_to_null(Field *field); +bool set_field_to_null_with_conversions(Field *field); uint find_enum(TYPELIB *typelib,const char *x, uint length); ulonglong find_set(TYPELIB *typelib,const char *x, uint length); bool test_if_int(const char *str,int length); diff --git a/sql/field_conv.cc b/sql/field_conv.cc index da7a1187a47..efb7401779c 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -112,35 +112,52 @@ static void do_outer_field_to_null_str(Copy_field *copy) bool set_field_to_null(Field *field) { - if (field->maybe_null()) + if (field->real_maybe_null()) { field->set_null(); field->reset(); + return 0; } - else + return 1; +} + + +bool +set_field_to_null_with_conversions(Field *field) +{ + if (field->real_maybe_null()) { - if (field->type() == FIELD_TYPE_TIMESTAMP) - { - ((Field_timestamp*) field)->set_time(); - return 0; // Ok to set time to NULL - } + field->set_null(); field->reset(); - if (field == field->table->next_number_field) - return 0; // field is set in handler.cc - if (current_thd->count_cuted_fields) - { - current_thd->cuted_fields++; // Increment error counter - return 0; - } - if (!current_thd->no_errors) - my_printf_error(ER_BAD_NULL_ERROR,ER(ER_BAD_NULL_ERROR),MYF(0), - field->field_name); - return 1; + return 0; + } + + /* + Check if this is a special type, which will get a special walue + when set to NULL + */ + if (field->type() == FIELD_TYPE_TIMESTAMP) + { + ((Field_timestamp*) field)->set_time(); + return 0; // Ok to set time to NULL + } + field->reset(); + if (field == field->table->next_number_field) + return 0; // field is set in handler.cc + if (current_thd->count_cuted_fields) + { + current_thd->cuted_fields++; // Increment error counter + return 0; } - return 0; + if (!current_thd->no_errors) + my_printf_error(ER_BAD_NULL_ERROR,ER(ER_BAD_NULL_ERROR),MYF(0), + field->field_name); + return 1; } + + static void do_skip(Copy_field *copy __attribute__((unused))) { } diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index f75f431ad52..1609064d4d5 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -2181,16 +2181,8 @@ convert_search_mode_to_innobase( case HA_READ_AFTER_KEY: return(PAGE_CUR_G); case HA_READ_BEFORE_KEY: return(PAGE_CUR_L); case HA_READ_PREFIX: return(PAGE_CUR_GE); - case HA_READ_PREFIX_LAST: - /* ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Warning: Using HA_READ_PREFIX_LAST\n"); */ - return(PAGE_CUR_LE); - - /* InnoDB does not yet support ..PREFIX_LAST! - We have to add a new search flag - PAGE_CUR_LE_OR_PREFIX to InnoDB. */ - + case HA_READ_PREFIX_LAST: return(PAGE_CUR_LE); + /* HA_READ_PREFIX_LAST does not yet work in InnoDB! */ /* the above PREFIX flags mean that the last field in the key value may just be a prefix of the complete fixed length field */ @@ -3264,7 +3256,7 @@ ha_innobase::records_in_range( MYF(MY_WME)); dtuple_t* range_start; dtuple_t* range_end; - ulint n_rows; + ib_longlong n_rows; ulint mode1; ulint mode2; void* heap1; @@ -3649,6 +3641,47 @@ ha_innobase::reset(void) return(0); } + +/********************************************************************** +When we create a temporary table inside MySQL LOCK TABLES, MySQL will +not call external_lock for the temporary table when it uses it. Instead, +it will call this function. */ + +int +ha_innobase::start_stmt( +/*====================*/ + /* out: 0 or error code */ + THD* thd) /* in: handle to the user thread */ +{ + row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; + trx_t* trx; + + update_thd(thd); + + trx = prebuilt->trx; + + innobase_release_stat_resources(trx); + trx_mark_sql_stat_end(trx); + + auto_inc_counter_for_this_stat = 0; + prebuilt->sql_stat_start = TRUE; + prebuilt->hint_no_need_to_fetch_extra_cols = TRUE; + prebuilt->read_just_key = 0; + + if (prebuilt->select_lock_type == LOCK_NONE) { + /* This handle is for a temporary table created inside + this same LOCK TABLES; since MySQL does NOT call external_lock + in this case, we must use x-row locks inside InnoDB to be + prepared for an update of a row */ + + prebuilt->select_lock_type = LOCK_X; + } + + thd->transaction.all.innodb_active_trans = 1; + + return(0); +} + /********************************************************************** When we create a temporary table inside MySQL LOCK TABLES, MySQL will not call external_lock for the temporary table when it uses it. Instead, @@ -3787,6 +3820,14 @@ innodb_show_status( DBUG_ENTER("innodb_show_status"); + if (innodb_skip) { + + fprintf(stderr, + "Cannot call SHOW INNODB STATUS because skip-innodb is defined\n"); + + DBUG_RETURN(-1); + } + /* We let the InnoDB Monitor to output at most 100 kB of text, add a safety margin of 10 kB for buffer overruns */ diff --git a/sql/item.cc b/sql/item.cc index a0cb6f46f06..f08696da715 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -595,7 +595,7 @@ void Item_field::save_org_in_field(Field *to) if (field->is_null()) { null_value=1; - set_field_to_null(to); + set_field_to_null_with_conversions(to); } else { @@ -610,7 +610,7 @@ int Item_field::save_in_field(Field *to) if (result_field->is_null()) { null_value=1; - return set_field_to_null(to); + return set_field_to_null_with_conversions(to); } else { @@ -622,7 +622,19 @@ int Item_field::save_in_field(Field *to) } -int Item_null::save_in_field(Field *field) +/* + Store null in field + + SYNOPSIS + save_safe_in_field() + field Field where we want to store NULL + + RETURN VALUES + 0 ok + 1 Field doesn't support NULL values +*/ + +int Item_null::save_safe_in_field(Field *field) { return set_field_to_null(field); } @@ -641,7 +653,7 @@ int Item::save_in_field(Field *field) str_value.set_quick(buff,sizeof(buff),cs); result=val_str(&str_value); if (null_value) - return set_field_to_null(field); + return set_field_to_null_with_conversions(field); field->set_notnull(); error=field->store(result->ptr(),result->length(),cs); str_value.set_quick(0, 0, cs); @@ -658,7 +670,7 @@ int Item::save_in_field(Field *field) { longlong nr=val_int(); if (null_value) - return set_field_to_null(field); + return set_field_to_null_with_conversions(field); field->set_notnull(); error=field->store(nr); } diff --git a/sql/item.h b/sql/item.h index 84182203d4c..0a46974f2e3 100644 --- a/sql/item.h +++ b/sql/item.h @@ -56,6 +56,8 @@ public: virtual int save_in_field(Field *field); virtual void save_org_in_field(Field *field) { (void) save_in_field(field); } + virtual bool save_safe_in_field(Field *field) + { return save_in_field(field); } virtual bool send(THD *thd, String *str); virtual bool eq(const Item *, bool binary_cmp) const; virtual Item_result result_type () const { return REAL_RESULT; } @@ -154,6 +156,7 @@ public: String *val_str(String *str); void make_field(Send_field *field); int save_in_field(Field *field); + int save_safe_in_field(Field *field); enum Item_result result_type () const { return STRING_RESULT; } bool send(THD *thd, String *str); diff --git a/sql/log.cc b/sql/log.cc index 8cb1577d745..91ef42e1381 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -942,8 +942,8 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command, int error= 0; VOID(pthread_mutex_lock(&LOCK_log)); - /* Test if someone closed after the is_open test */ - if (log_type != LOG_CLOSED) + /* Test if someone closed between the is_open test and lock */ + if (is_open()) { time_t skr; ulong id; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 8497fe90758..76d19f50f96 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3321,7 +3321,8 @@ struct my_option my_long_options[] = (gptr*) &opt_mysql_tmpdir, (gptr*) &opt_mysql_tmpdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"transaction-isolation", OPT_TX_ISOLATION, - "Default transaction isolation level", 0, 0, 0, GET_NO_ARG, REQUIRED_ARG, 0, + "Default transaction isolation level", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, + 0, 0, 0, 0, 0}, 0, 0, 0, 0, 0}, {"external-locking", OPT_USE_LOCKING, "Use system (external) locking. With this option enabled you can run myisamchk to test (not repair) tables while the MySQL server is running", (gptr*) &opt_external_locking, (gptr*) &opt_external_locking, @@ -3375,7 +3376,7 @@ struct my_option my_long_options[] = (gptr*) &connect_timeout, (gptr*) &connect_timeout, 0, GET_ULONG, REQUIRED_ARG, CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1, 0 }, {"delayed_insert_timeout", OPT_DELAYED_INSERT_TIMEOUT, - "Ho wlong a INSERT DELAYED thread should wait for INSERT statements before terminating.", + "How long a INSERT DELAYED thread should wait for INSERT statements before terminating.", (gptr*) &delayed_insert_timeout, (gptr*) &delayed_insert_timeout, 0, GET_ULONG, REQUIRED_ARG, DELAYED_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0}, {"delayed_insert_limit", OPT_DELAYED_INSERT_LIMIT, @@ -4171,7 +4172,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case (int) OPT_SKIP_SHOW_DB: opt_skip_show_db=1; opt_specialflag|=SPECIAL_SKIP_SHOW_DB; - mysql_port=0; break; #ifdef ONE_THREAD case (int) OPT_ONE_THREAD: diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e096ef7869e..848645c6f25 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3569,10 +3569,10 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables) } if (options & REFRESH_LOG) { - mysql_log.new_file(); - mysql_update_log.new_file(); - mysql_bin_log.new_file(); - mysql_slow_log.new_file(); + mysql_log.new_file(0); + mysql_update_log.new_file(0); + mysql_bin_log.new_file(0); + mysql_slow_log.new_file(0); if (ha_flush_logs()) result=1; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 399bbbb5e66..6c51b6bf9a8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -113,6 +113,8 @@ static uint find_shortest_key(TABLE *table, key_map usable_keys); static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order, ha_rows select_limit, bool no_changes); static int create_sort_index(THD *thd, JOIN_TAB *tab,ORDER *order, + ha_rows filesort_limit, ha_rows select_limit); +static int create_sort_index(THD *thd, JOIN_TAB *tab,ORDER *order, ha_rows select_limit); static int remove_duplicates(JOIN *join,TABLE *entry,List<Item> &fields, Item *having); @@ -750,7 +752,7 @@ JOIN::exec() DBUG_PRINT("info",("Sorting for group")); thd->proc_info="Sorting for group"; if (create_sort_index(thd, &join_tab[const_tables], group_list, - HA_POS_ERROR) || + HA_POS_ERROR, HA_POS_ERROR) || make_sum_func_list(this, all_fields) || alloc_group_fields(this, group_list)) DBUG_VOID_RETURN; @@ -765,7 +767,7 @@ JOIN::exec() DBUG_PRINT("info",("Sorting for order")); thd->proc_info="Sorting for order"; if (create_sort_index(thd, &join_tab[const_tables], order, - HA_POS_ERROR)) + HA_POS_ERROR, HA_POS_ERROR)) DBUG_VOID_RETURN; order=0; } @@ -867,7 +869,8 @@ JOIN::exec() if (group_list) { thd->proc_info="Creating sort index"; - if (create_sort_index(thd, join_tab, group_list, HA_POS_ERROR) || + if (create_sort_index(thd, join_tab, group_list, HA_POS_ERROR, + HA_POS_ERROR) || alloc_group_fields(this, group_list)) { free_tmp_table(thd,tmp_table2); /* purecov: inspected */ @@ -963,12 +966,33 @@ JOIN::exec() DBUG_EXECUTE("where",print_where(conds,"having after sort");); } } - if (create_sort_index(thd, &join_tab[const_tables], - group_list ? group_list : order, - (having_list || group_list || - (select_options & OPTION_FOUND_ROWS)) ? - HA_POS_ERROR : unit->select_limit_cnt)) - DBUG_VOID_RETURN; + { + ha_rows select_limit= unit->select_limit_cnt; + if (having || group || (select_options & OPTION_FOUND_ROWS)) + select_limit= HA_POS_ERROR; + else + { + /* + We can abort sorting after thd->select_limit rows if we there is no + WHERE clause for any tables after the sorted one. + */ + JOIN_TAB *table= &join_tab[join.const_tables+1]; + JOIN_TAB *end_table= &join_tab[join.tables]; + for (; table < end_table ; table++) + { + if (table->select_cond) + { + /* We have to sort all rows */ + select_limit= HA_POS_ERROR; + break; + } + } + } + if (create_sort_index(thd, &join_tab[const_tables], + group_list ? group_list : order, + select_limit, unit->select_limit_cnt)) + DBUG_VOID_RETURN; + } } having=having_list; // Actually a parameter thd->proc_info="Sending data"; @@ -3665,7 +3689,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, char *tmpname,path[FN_REFLEN]; byte *pos,*group_buff; uchar *null_flags; - Field **reg_field,**from_field; + Field **reg_field, **from_field, **blob_field; Copy_field *copy=0; KEY *keyinfo; KEY_PART_INFO *key_part_info; @@ -3710,8 +3734,9 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, hidden_field_count=param->hidden_field_count; if (!my_multi_malloc(MYF(MY_WME), &table,sizeof(*table), - ®_field,sizeof(Field*)*(field_count+1), - &from_field,sizeof(Field*)*field_count, + ®_field, sizeof(Field*)*(field_count+1), + &blob_field, sizeof(Field*)*(field_count+1), + &from_field, sizeof(Field*)*field_count, ©_func,sizeof(*copy_func)*(param->func_count+1), ¶m->keyinfo,sizeof(*param->keyinfo), &key_part_info, @@ -3740,8 +3765,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, bzero((char*) reg_field,sizeof(Field*)*(field_count+1)); bzero((char*) from_field,sizeof(Field*)*field_count); table->field=reg_field; + table->blob_field= (Field_blob**) blob_field; table->real_name=table->path=tmpname; - table->table_name=base_name(tmpname); + /* + This must be "" as field may refer to it after tempory table is dropped + */ + table->table_name= (char*) ""; table->reginfo.lock_type=TL_WRITE; /* Will be updated */ table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE; table->blob_ptr_size=mi_portable_sizeof_char_ptr; @@ -3750,7 +3779,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, table->derived_select_number= 0; table->db_low_byte_first=1; // True for HEAP and MyISAM table->temp_pool_slot = temp_pool_slot; - + table->copy_blobs= 1; /* Calculate which type of fields we will store in the temporary table */ @@ -3797,7 +3826,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, if (!(new_field->flags & NOT_NULL_FLAG)) null_count++; if (new_field->flags & BLOB_FLAG) + { + *blob_field++= new_field; blob_count++; + } ((Item_sum*) item)->args[i]= new Item_field(new_field); } } @@ -3820,7 +3852,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, if (!(new_field->flags & NOT_NULL_FLAG)) null_count++; if (new_field->flags & BLOB_FLAG) + { + *blob_field++= new_field; blob_count++; + } if (item->marker == 4 && item->maybe_null) { group_null_items++; @@ -3833,6 +3868,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, } DBUG_ASSERT(field_count >= (uint) (reg_field - table->field)); field_count= (uint) (reg_field - table->field); + *blob_field= 0; // End marker /* If result table is small; use a heap */ if (blob_count || using_unique_constraint || group_null_items || @@ -4090,10 +4126,17 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, if (create_myisam_tmp_table(table,param,select_options)) goto err; } + /* Set table_name for easier debugging */ + table->table_name= base_name(tmpname); if (!open_tmp_table(table)) DBUG_RETURN(table); err: + /* + Hack to ensure that free_blobs() doesn't fail if blob_field is not yet + complete + */ + *table->blob_field= 0; free_tmp_table(thd,table); /* purecov: inspected */ bitmap_clear_bit(&temp_pool, temp_pool_slot); DBUG_RETURN(NULL); /* purecov: inspected */ @@ -4238,6 +4281,7 @@ free_tmp_table(THD *thd, TABLE *entry) save_proc_info=thd->proc_info; thd->proc_info="removing tmp table"; + free_blobs(entry); if (entry->db_stat && entry->file) { (void) entry->file->close(); @@ -5796,7 +5840,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, *****************************************************************************/ static int -create_sort_index(THD *thd, JOIN_TAB *tab,ORDER *order,ha_rows select_limit) +create_sort_index(THD *thd, JOIN_TAB *tab, ORDER *order, + ha_rows filesort_limit, ha_rows select_limit) { SORT_FIELD *sortorder; uint length; @@ -5841,7 +5886,7 @@ create_sort_index(THD *thd, JOIN_TAB *tab,ORDER *order,ha_rows select_limit) if (table->tmp_table) table->file->info(HA_STATUS_VARIABLE); // Get record count table->found_records=filesort(thd, table,sortorder, length, - select, select_limit, &examined_rows); + select, filesort_limit, &examined_rows); tab->records=table->found_records; // For SQL_CALC_ROWS delete select; // filesort did select tab->select=0; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index f7ab07b2da3..1786d1ef93f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -520,6 +520,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %left '^' %right NOT %right BINARY COLLATE_SYM +/* These don't actually affect the way the query is really evaluated, but + they silence a few warnings for shift/reduce conflicts. */ +%left ',' +%left STRAIGHT_JOIN JOIN_SYM +%nonassoc CROSS INNER_SYM NATURAL LEFT RIGHT %type <lex_str> IDENT TEXT_STRING REAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM LEX_HOSTNAME @@ -2209,11 +2214,12 @@ opt_pad: join_table_list: '(' join_table_list ')' { $$=$2; } | join_table { $$=$1; } - | join_table_list normal_join join_table { $$=$3; } - | join_table_list STRAIGHT_JOIN join_table { $$=$3 ; $$->straight=1; } - | join_table_list INNER_SYM JOIN_SYM join_table ON expr + | join_table_list normal_join join_table_list { $$=$3; } + | join_table_list STRAIGHT_JOIN join_table_list + { $$=$3 ; $$->straight=1; } + | join_table_list INNER_SYM JOIN_SYM join_table_list ON expr { add_join_on($4,$6); $$=$4; } - | join_table_list INNER_SYM JOIN_SYM join_table + | join_table_list INNER_SYM JOIN_SYM join_table_list { SELECT_LEX *sel=Select; sel->db1=$1->db; sel->table1=$1->alias; @@ -2221,9 +2227,9 @@ join_table_list: } USING '(' using_list ')' { add_join_on($4,$8); $$=$4; } - | join_table_list LEFT opt_outer JOIN_SYM join_table ON expr + | join_table_list LEFT opt_outer JOIN_SYM join_table_list ON expr { add_join_on($5,$7); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; } - | join_table_list LEFT opt_outer JOIN_SYM join_table + | join_table_list LEFT opt_outer JOIN_SYM join_table_list { SELECT_LEX *sel=Select; sel->db1=$1->db; sel->table1=$1->alias; @@ -2231,11 +2237,11 @@ join_table_list: } USING '(' using_list ')' { add_join_on($5,$9); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; } - | join_table_list NATURAL LEFT opt_outer JOIN_SYM join_table + | join_table_list NATURAL LEFT opt_outer JOIN_SYM join_table_list { add_join_natural($1,$6); $6->outer_join|=JOIN_TYPE_LEFT; $$=$6; } - | join_table_list RIGHT opt_outer JOIN_SYM join_table ON expr + | join_table_list RIGHT opt_outer JOIN_SYM join_table_list ON expr { add_join_on($1,$7); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$1; } - | join_table_list RIGHT opt_outer JOIN_SYM join_table + | join_table_list RIGHT opt_outer JOIN_SYM join_table_list { SELECT_LEX *sel=Select; sel->db1=$1->db; sel->table1=$1->alias; @@ -2243,9 +2249,9 @@ join_table_list: } USING '(' using_list ')' { add_join_on($1,$9); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$1; } - | join_table_list NATURAL RIGHT opt_outer JOIN_SYM join_table + | join_table_list NATURAL RIGHT opt_outer JOIN_SYM join_table_list { add_join_natural($6,$1); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$1; } - | join_table_list NATURAL JOIN_SYM join_table + | join_table_list NATURAL JOIN_SYM join_table_list { add_join_natural($1,$4); $$=$4; }; normal_join: @@ -3566,6 +3572,7 @@ option_value: { Lex->var_list.push_back(new set_var_password($3,$5)); } + ; internal_variable_name: ident @@ -3575,6 +3582,7 @@ internal_variable_name: YYABORT; $$=tmp; } + ; isolation_types: READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; } @@ -3934,6 +3942,7 @@ require_clause: /* empty */ { Lex->ssl_type=SSL_TYPE_NONE; } + ; grant_options: /* empty */ {} diff --git a/sql/table.cc b/sql/table.cc index 2cdd62001f1..122cce160b6 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -527,6 +527,13 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, field->field_length=key_part->length; } } + /* + If the field can be NULL, don't optimize away the test + key_part_column = expression from the WHERE clause + as we need to test for NULL = NULL. + */ + if (field->real_maybe_null()) + key_part->key_part_flag|= HA_PART_KEY; } else { // Error: shorten key |