Merge lp:~stewart/drizzle/update-innobase-1.1.3 into lp:drizzle/7.0

Proposed by Stewart Smith
Status: Merged
Merged at revision: 1986
Proposed branch: lp:~stewart/drizzle/update-innobase-1.1.3
Merge into: lp:drizzle/7.0
Diff against target: 3297 lines (+880/-956)
71 files modified
drizzled/function/min_max.cc (+15/-1)
drizzled/session.cc (+1/-1)
drizzled/sql_insert.cc (+2/-3)
drizzled/sql_update.cc (+1/-10)
drizzled/table.cc (+61/-5)
drizzled/table.h (+2/-1)
plugin/innobase/COPYING (+0/-351)
plugin/innobase/COPYING.Sun_Microsystems (+0/-31)
plugin/innobase/ChangeLog (+26/-0)
plugin/innobase/Doxyfile (+1/-1)
plugin/innobase/btr/btr0btr.c (+4/-7)
plugin/innobase/btr/btr0cur.c (+16/-6)
plugin/innobase/btr/btr0pcur.c (+0/-2)
plugin/innobase/btr/btr0sea.c (+1/-2)
plugin/innobase/buf/buf0flu.c (+6/-1)
plugin/innobase/dict/dict0crea.c (+0/-2)
plugin/innobase/dict/dict0dict.c (+40/-37)
plugin/innobase/dict/dict0load.c (+89/-23)
plugin/innobase/eval/eval0eval.c (+1/-6)
plugin/innobase/handler/ha_innodb.cc (+58/-36)
plugin/innobase/ibuf/ibuf0ibuf.c (+6/-13)
plugin/innobase/include/btr0cur.h (+3/-2)
plugin/innobase/include/buf0flu.h (+2/-2)
plugin/innobase/include/db0err.h (+3/-0)
plugin/innobase/include/dict0dict.h (+16/-0)
plugin/innobase/include/dict0dict.ic (+42/-0)
plugin/innobase/include/dict0load.h (+2/-0)
plugin/innobase/include/dict0mem.h (+21/-0)
plugin/innobase/include/os0sync.h (+1/-1)
plugin/innobase/include/que0que.h (+3/-0)
plugin/innobase/include/srv0srv.h (+3/-1)
plugin/innobase/include/univ.i (+1/-13)
plugin/innobase/include/ut0rbt.h (+1/-1)
plugin/innobase/include/ut0rnd.ic (+0/-3)
plugin/innobase/log/log0recv.c (+4/-6)
plugin/innobase/os/os0file.c (+3/-22)
plugin/innobase/plugin.am (+1/-7)
plugin/innobase/plugin.ini (+1/-3)
plugin/innobase/que/que0que.c (+0/-5)
plugin/innobase/row/row0merge.c (+1/-1)
plugin/innobase/row/row0mysql.c (+54/-3)
plugin/innobase/row/row0purge.c (+9/-2)
plugin/innobase/row/row0sel.c (+60/-45)
plugin/innobase/row/row0umod.c (+6/-1)
plugin/innobase/row/row0upd.c (+7/-5)
plugin/innobase/row/row0vers.c (+8/-3)
plugin/innobase/srv/srv0srv.c (+20/-1)
plugin/innobase/srv/srv0start.c (+20/-1)
plugin/innobase/tests/r/index_merge_innodb.result (+55/-0)
plugin/innobase/tests/r/innodb_bug56716.result (+4/-0)
plugin/innobase/tests/r/innodb_bug57255.result (+10/-0)
plugin/innobase/tests/r/innodb_mysql.result (+32/-0)
plugin/innobase/tests/t/innodb-autoinc.test (+12/-0)
plugin/innobase/tests/t/innodb_bug53756.test (+2/-2)
plugin/innobase/tests/t/innodb_bug56716.test (+10/-0)
plugin/innobase/tests/t/innodb_bug57255.test (+38/-0)
plugin/innobase/tests/t/innodb_mysql.test (+28/-0)
plugin/innobase/trx/trx0purge.c (+4/-8)
plugin/innobase/trx/trx0roll.c (+0/-5)
plugin/innobase/trx/trx0sys.c (+7/-2)
plugin/innobase/trx/trx0trx.c (+1/-2)
plugin/innobase/trx/trx0undo.c (+0/-5)
plugin/innobase/ut/ut0auxconf_atomic_pthread_t_gcc.c (+0/-43)
plugin/innobase/ut/ut0auxconf_atomic_pthread_t_solaris.c (+0/-54)
plugin/innobase/ut/ut0auxconf_have_gcc_atomics.c (+0/-61)
plugin/innobase/ut/ut0auxconf_have_solaris_atomics.c (+0/-39)
plugin/innobase/ut/ut0auxconf_pause.c (+0/-32)
plugin/innobase/ut/ut0auxconf_sizeof_pthread_t.c (+0/-35)
plugin/innobase/ut/ut0ut.c (+2/-0)
po/POTFILES.in (+0/-1)
tests/include/index_merge2.inc (+53/-0)
To merge this branch: bzr merge lp:~stewart/drizzle/update-innobase-1.1.3
Reviewer Review Type Date Requested Status
Drizzle Developers Pending
Review via email: mp+42948@code.launchpad.net

Description of the change

Innobase 1.1.3 from MySQL 5.5.7

http://hudson.drizzle.org/view/Drizzle-param/job/drizzle-param/656/

seems to be building well.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'drizzled/function/min_max.cc'
2--- drizzled/function/min_max.cc 2010-06-22 01:08:50 +0000
3+++ drizzled/function/min_max.cc 2010-12-07 14:26:13 +0000
4@@ -79,7 +79,7 @@
5 stored to the value pointer, if latter is provided.
6
7 RETURN
8- 0 If one of arguments is NULL
9+ 0 If one of arguments is NULL or there was a execution error
10 # index of the least/greatest argument
11 */
12
13@@ -94,6 +94,14 @@
14 bool is_null_unused;
15 uint64_t res= get_datetime_value(session, &arg, 0, datetime_item,
16 &is_null_unused);
17+
18+ /* Check if we need to stop (because of error or KILL) and stop the loop */
19+ if (session->is_error())
20+ {
21+ null_value= 1;
22+ return 0;
23+ }
24+
25 if ((null_value= args[i]->null_value))
26 return 0;
27 if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0)
28@@ -122,6 +130,12 @@
29 if (null_value)
30 return 0;
31 str_res= args[min_max_idx]->val_str(str);
32+ if (args[min_max_idx]->null_value)
33+ {
34+ // check if the call to val_str() above returns a NULL value
35+ null_value= 1;
36+ return NULL;
37+ }
38 str_res->set_charset(collation.collation);
39 return str_res;
40 }
41
42=== modified file 'drizzled/session.cc'
43--- drizzled/session.cc 2010-12-03 19:21:28 +0000
44+++ drizzled/session.cc 2010-12-07 14:26:13 +0000
45@@ -86,7 +86,7 @@
46 {
47 return length == other.length &&
48 field_name.length == other.field_name.length &&
49- !strcmp(field_name.str, other.field_name.str);
50+ !my_strcasecmp(system_charset_info, field_name.str, other.field_name.str);
51 }
52
53 Open_tables_state::Open_tables_state(uint64_t version_arg) :
54
55=== modified file 'drizzled/sql_insert.cc'
56--- drizzled/sql_insert.cc 2010-11-28 00:06:17 +0000
57+++ drizzled/sql_insert.cc 2010-12-07 14:26:13 +0000
58@@ -846,9 +846,8 @@
59 table->cursor->adjust_next_insert_id_after_explicit_value(
60 table->next_number_field->val_int());
61 info->touched++;
62- if ((table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) &&
63- ! table->write_set->is_subset_of(*table->read_set)) ||
64- table->compare_record())
65+
66+ if (! table->records_are_comparable() || table->compare_records())
67 {
68 if ((error=table->cursor->updateRecord(table->getUpdateRecord(),
69 table->getInsertRecord())) &&
70
71=== modified file 'drizzled/sql_update.cc'
72--- drizzled/sql_update.cc 2010-11-15 20:17:18 +0000
73+++ drizzled/sql_update.cc 2010-12-07 14:26:13 +0000
74@@ -136,7 +136,6 @@
75 bool using_limit= limit != HA_POS_ERROR;
76 bool used_key_is_modified;
77 bool transactional_table;
78- bool can_compare_record;
79 int error;
80 uint used_index= MAX_KEY, dup_key_found;
81 bool need_sort= true;
82@@ -459,14 +458,6 @@
83 if (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ))
84 table->prepare_for_position();
85
86- /*
87- We can use compare_record() to optimize away updates if
88- the table handler is returning all columns OR if
89- if all updated columns are read
90- */
91- can_compare_record= (! (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ)) ||
92- table->write_set->is_subset_of(*table->read_set));
93-
94 while (not (error=info.read_record(&info)) && not session->getKilled())
95 {
96 if (not (select && select->skip_record()))
97@@ -493,7 +484,7 @@
98
99 found++;
100
101- if (!can_compare_record || table->compare_record())
102+ if (! table->records_are_comparable() || table->compare_records())
103 {
104 /* Non-batched update */
105 error= table->cursor->updateRecord(table->getUpdateRecord(),
106
107=== modified file 'drizzled/table.cc'
108--- drizzled/table.cc 2010-11-06 05:47:12 +0000
109+++ drizzled/table.cc 2010-12-07 14:26:13 +0000
110@@ -1472,13 +1472,69 @@
111 return false;
112 }
113
114-/* Return false if row hasn't changed */
115-
116-bool Table::compare_record()
117-{
118+/**
119+ True if the table's input and output record buffers are comparable using
120+ compare_records(TABLE*).
121+ */
122+bool Table::records_are_comparable()
123+{
124+ return ((getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) == 0) ||
125+ write_set->is_subset_of(*read_set));
126+}
127+
128+/**
129+ Compares the input and outbut record buffers of the table to see if a row
130+ has changed. The algorithm iterates over updated columns and if they are
131+ nullable compares NULL bits in the buffer before comparing actual
132+ data. Special care must be taken to compare only the relevant NULL bits and
133+ mask out all others as they may be undefined. The storage engine will not
134+ and should not touch them.
135+
136+ @param table The table to evaluate.
137+
138+ @return true if row has changed.
139+ @return false otherwise.
140+*/
141+bool Table::compare_records()
142+{
143+// DBUG_ASSERT(records_are_comparable(table));
144+
145+ if (getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) != 0)
146+ {
147+ /*
148+ Storage engine may not have read all columns of the record. Fields
149+ (including NULL bits) not in the write_set may not have been read and
150+ can therefore not be compared.
151+ */
152+ for (Field **ptr= this->field ; *ptr != NULL; ptr++)
153+ {
154+ Field *f= *ptr;
155+ if (write_set->test(f->field_index))
156+ {
157+ if (f->real_maybe_null())
158+ {
159+ unsigned char null_byte_index= f->null_ptr - record[0];
160+
161+ if (((record[0][null_byte_index]) & f->null_bit) !=
162+ ((record[1][null_byte_index]) & f->null_bit))
163+ return true;
164+ }
165+ if (f->cmp_binary_offset(getShare()->rec_buff_length))
166+ return true;
167+ }
168+ }
169+ return false;
170+ }
171+
172+ /*
173+ The storage engine has read all columns, so it's safe to compare all bits
174+ including those not in the write_set. This is cheaper than the
175+ field-by-field comparison done above.
176+ */
177 if (not getShare()->blob_fields + getShare()->hasVariableWidth())
178+ // Fixed-size record: do bitwise comparison of the records
179 return memcmp(this->getInsertRecord(), this->getUpdateRecord(), (size_t) getShare()->getRecordLength());
180-
181+
182 /* Compare null bits */
183 if (memcmp(null_flags, null_flags + getShare()->rec_buff_length, getShare()->null_bytes))
184 return true; /* Diff in NULL value */
185
186=== modified file 'drizzled/table.h'
187--- drizzled/table.h 2010-11-08 21:03:52 +0000
188+++ drizzled/table.h 2010-12-07 14:26:13 +0000
189@@ -437,7 +437,8 @@
190 size_t max_row_length(const unsigned char *data);
191 uint32_t find_shortest_key(const key_map *usable_keys);
192 bool compare_record(Field **ptr);
193- bool compare_record();
194+ bool records_are_comparable();
195+ bool compare_records();
196 /* TODO: the (re)storeRecord's may be able to be further condensed */
197 void storeRecord();
198 void storeRecordAsInsert();
199
200=== removed file 'plugin/innobase/COPYING'
201--- plugin/innobase/COPYING 2009-03-12 22:30:11 +0000
202+++ plugin/innobase/COPYING 1970-01-01 00:00:00 +0000
203@@ -1,351 +0,0 @@
204- GNU GENERAL PUBLIC LICENSE
205- Version 2, June 1991
206-
207- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
208- 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
209-
210- Everyone is permitted to copy and distribute verbatim copies
211- of this license document, but changing it is not allowed.
212-
213-Preamble
214-========
215-
216-The licenses for most software are designed to take away your freedom
217-to share and change it. By contrast, the GNU General Public License is
218-intended to guarantee your freedom to share and change free
219-software--to make sure the software is free for all its users. This
220-General Public License applies to most of the Free Software
221-Foundation's software and to any other program whose authors commit to
222-using it. (Some other Free Software Foundation software is covered by
223-the GNU Library General Public License instead.) You can apply it to
224-your programs, too.
225-
226-When we speak of free software, we are referring to freedom, not price.
227-Our General Public Licenses are designed to make sure that you have
228-the freedom to distribute copies of free software (and charge for this
229-service if you wish), that you receive source code or can get it if you
230-want it, that you can change the software or use pieces of it in new
231-free programs; and that you know you can do these things.
232-
233-To protect your rights, we need to make restrictions that forbid anyone
234-to deny you these rights or to ask you to surrender the rights. These
235-restrictions translate to certain responsibilities for you if you
236-distribute copies of the software, or if you modify it.
237-
238-For example, if you distribute copies of such a program, whether gratis
239-or for a fee, you must give the recipients all the rights that you
240-have. You must make sure that they, too, receive or can get the source
241-code. And you must show them these terms so they know their rights.
242-
243-We protect your rights with two steps: (1) copyright the software, and
244-(2) offer you this license which gives you legal permission to copy,
245-distribute and/or modify the software.
246-
247-Also, for each author's protection and ours, we want to make certain
248-that everyone understands that there is no warranty for this free
249-software. If the software is modified by someone else and passed on, we
250-want its recipients to know that what they have is not the original, so
251-that any problems introduced by others will not reflect on the original
252-authors' reputations.
253-
254-Finally, any free program is threatened constantly by software patents.
255-We wish to avoid the danger that redistributors of a free program will
256-individually obtain patent licenses, in effect making the program
257-proprietary. To prevent this, we have made it clear that any patent
258-must be licensed for everyone's free use or not licensed at all.
259-
260-The precise terms and conditions for copying, distribution and
261-modification follow.
262-
263- GNU GENERAL PUBLIC LICENSE
264- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
265- 0. This License applies to any program or other work which contains a
266- notice placed by the copyright holder saying it may be distributed
267- under the terms of this General Public License. The "Program",
268- below, refers to any such program or work, and a "work based on
269- the Program" means either the Program or any derivative work under
270- copyright law: that is to say, a work containing the Program or a
271- portion of it, either verbatim or with modifications and/or
272- translated into another language. (Hereinafter, translation is
273- included without limitation in the term "modification".) Each
274- licensee is addressed as "you".
275-
276- Activities other than copying, distribution and modification are
277- not covered by this License; they are outside its scope. The act
278- of running the Program is not restricted, and the output from the
279- Program is covered only if its contents constitute a work based on
280- the Program (independent of having been made by running the
281- Program). Whether that is true depends on what the Program does.
282-
283- 1. You may copy and distribute verbatim copies of the Program's
284- source code as you receive it, in any medium, provided that you
285- conspicuously and appropriately publish on each copy an appropriate
286- copyright notice and disclaimer of warranty; keep intact all the
287- notices that refer to this License and to the absence of any
288- warranty; and give any other recipients of the Program a copy of
289- this License along with the Program.
290-
291- You may charge a fee for the physical act of transferring a copy,
292- and you may at your option offer warranty protection in exchange
293- for a fee.
294-
295- 2. You may modify your copy or copies of the Program or any portion
296- of it, thus forming a work based on the Program, and copy and
297- distribute such modifications or work under the terms of Section 1
298- above, provided that you also meet all of these conditions:
299-
300- a. You must cause the modified files to carry prominent notices
301- stating that you changed the files and the date of any change.
302-
303- b. You must cause any work that you distribute or publish, that
304- in whole or in part contains or is derived from the Program
305- or any part thereof, to be licensed as a whole at no charge
306- to all third parties under the terms of this License.
307-
308- c. If the modified program normally reads commands interactively
309- when run, you must cause it, when started running for such
310- interactive use in the most ordinary way, to print or display
311- an announcement including an appropriate copyright notice and
312- a notice that there is no warranty (or else, saying that you
313- provide a warranty) and that users may redistribute the
314- program under these conditions, and telling the user how to
315- view a copy of this License. (Exception: if the Program
316- itself is interactive but does not normally print such an
317- announcement, your work based on the Program is not required
318- to print an announcement.)
319-
320- These requirements apply to the modified work as a whole. If
321- identifiable sections of that work are not derived from the
322- Program, and can be reasonably considered independent and separate
323- works in themselves, then this License, and its terms, do not
324- apply to those sections when you distribute them as separate
325- works. But when you distribute the same sections as part of a
326- whole which is a work based on the Program, the distribution of
327- the whole must be on the terms of this License, whose permissions
328- for other licensees extend to the entire whole, and thus to each
329- and every part regardless of who wrote it.
330-
331- Thus, it is not the intent of this section to claim rights or
332- contest your rights to work written entirely by you; rather, the
333- intent is to exercise the right to control the distribution of
334- derivative or collective works based on the Program.
335-
336- In addition, mere aggregation of another work not based on the
337- Program with the Program (or with a work based on the Program) on
338- a volume of a storage or distribution medium does not bring the
339- other work under the scope of this License.
340-
341- 3. You may copy and distribute the Program (or a work based on it,
342- under Section 2) in object code or executable form under the terms
343- of Sections 1 and 2 above provided that you also do one of the
344- following:
345-
346- a. Accompany it with the complete corresponding machine-readable
347- source code, which must be distributed under the terms of
348- Sections 1 and 2 above on a medium customarily used for
349- software interchange; or,
350-
351- b. Accompany it with a written offer, valid for at least three
352- years, to give any third-party, for a charge no more than your
353- cost of physically performing source distribution, a complete
354- machine-readable copy of the corresponding source code, to be
355- distributed under the terms of Sections 1 and 2 above on a
356- medium customarily used for software interchange; or,
357-
358- c. Accompany it with the information you received as to the offer
359- to distribute corresponding source code. (This alternative is
360- allowed only for noncommercial distribution and only if you
361- received the program in object code or executable form with
362- such an offer, in accord with Subsection b above.)
363-
364- The source code for a work means the preferred form of the work for
365- making modifications to it. For an executable work, complete
366- source code means all the source code for all modules it contains,
367- plus any associated interface definition files, plus the scripts
368- used to control compilation and installation of the executable.
369- However, as a special exception, the source code distributed need
370- not include anything that is normally distributed (in either
371- source or binary form) with the major components (compiler,
372- kernel, and so on) of the operating system on which the executable
373- runs, unless that component itself accompanies the executable.
374-
375- If distribution of executable or object code is made by offering
376- access to copy from a designated place, then offering equivalent
377- access to copy the source code from the same place counts as
378- distribution of the source code, even though third parties are not
379- compelled to copy the source along with the object code.
380-
381- 4. You may not copy, modify, sublicense, or distribute the Program
382- except as expressly provided under this License. Any attempt
383- otherwise to copy, modify, sublicense or distribute the Program is
384- void, and will automatically terminate your rights under this
385- License. However, parties who have received copies, or rights,
386- from you under this License will not have their licenses
387- terminated so long as such parties remain in full compliance.
388-
389- 5. You are not required to accept this License, since you have not
390- signed it. However, nothing else grants you permission to modify
391- or distribute the Program or its derivative works. These actions
392- are prohibited by law if you do not accept this License.
393- Therefore, by modifying or distributing the Program (or any work
394- based on the Program), you indicate your acceptance of this
395- License to do so, and all its terms and conditions for copying,
396- distributing or modifying the Program or works based on it.
397-
398- 6. Each time you redistribute the Program (or any work based on the
399- Program), the recipient automatically receives a license from the
400- original licensor to copy, distribute or modify the Program
401- subject to these terms and conditions. You may not impose any
402- further restrictions on the recipients' exercise of the rights
403- granted herein. You are not responsible for enforcing compliance
404- by third parties to this License.
405-
406- 7. If, as a consequence of a court judgment or allegation of patent
407- infringement or for any other reason (not limited to patent
408- issues), conditions are imposed on you (whether by court order,
409- agreement or otherwise) that contradict the conditions of this
410- License, they do not excuse you from the conditions of this
411- License. If you cannot distribute so as to satisfy simultaneously
412- your obligations under this License and any other pertinent
413- obligations, then as a consequence you may not distribute the
414- Program at all. For example, if a patent license would not permit
415- royalty-free redistribution of the Program by all those who
416- receive copies directly or indirectly through you, then the only
417- way you could satisfy both it and this License would be to refrain
418- entirely from distribution of the Program.
419-
420- If any portion of this section is held invalid or unenforceable
421- under any particular circumstance, the balance of the section is
422- intended to apply and the section as a whole is intended to apply
423- in other circumstances.
424-
425- It is not the purpose of this section to induce you to infringe any
426- patents or other property right claims or to contest validity of
427- any such claims; this section has the sole purpose of protecting
428- the integrity of the free software distribution system, which is
429- implemented by public license practices. Many people have made
430- generous contributions to the wide range of software distributed
431- through that system in reliance on consistent application of that
432- system; it is up to the author/donor to decide if he or she is
433- willing to distribute software through any other system and a
434- licensee cannot impose that choice.
435-
436- This section is intended to make thoroughly clear what is believed
437- to be a consequence of the rest of this License.
438-
439- 8. If the distribution and/or use of the Program is restricted in
440- certain countries either by patents or by copyrighted interfaces,
441- the original copyright holder who places the Program under this
442- License may add an explicit geographical distribution limitation
443- excluding those countries, so that distribution is permitted only
444- in or among countries not thus excluded. In such case, this
445- License incorporates the limitation as if written in the body of
446- this License.
447-
448- 9. The Free Software Foundation may publish revised and/or new
449- versions of the General Public License from time to time. Such
450- new versions will be similar in spirit to the present version, but
451- may differ in detail to address new problems or concerns.
452-
453- Each version is given a distinguishing version number. If the
454- Program specifies a version number of this License which applies
455- to it and "any later version", you have the option of following
456- the terms and conditions either of that version or of any later
457- version published by the Free Software Foundation. If the Program
458- does not specify a version number of this License, you may choose
459- any version ever published by the Free Software Foundation.
460-
461- 10. If you wish to incorporate parts of the Program into other free
462- programs whose distribution conditions are different, write to the
463- author to ask for permission. For software which is copyrighted
464- by the Free Software Foundation, write to the Free Software
465- Foundation; we sometimes make exceptions for this. Our decision
466- will be guided by the two goals of preserving the free status of
467- all derivatives of our free software and of promoting the sharing
468- and reuse of software generally.
469-
470- NO WARRANTY
471- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
472- WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
473- LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
474- HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
475- WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT
476- NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
477- FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE
478- QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
479- PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
480- SERVICING, REPAIR OR CORRECTION.
481-
482- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
483- WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY
484- MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE
485- LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
486- INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
487- INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
488- DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU
489- OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY
490- OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
491- ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
492-
493- END OF TERMS AND CONDITIONS
494-How to Apply These Terms to Your New Programs
495-=============================================
496-
497-If you develop a new program, and you want it to be of the greatest
498-possible use to the public, the best way to achieve this is to make it
499-free software which everyone can redistribute and change under these
500-terms.
501-
502-To do so, attach the following notices to the program. It is safest to
503-attach them to the start of each source file to most effectively convey
504-the exclusion of warranty; and each file should have at least the
505-"copyright" line and a pointer to where the full notice is found.
506-
507- ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES.
508- Copyright (C) YYYY NAME OF AUTHOR
509-
510- This program is free software; you can redistribute it and/or modify
511- it under the terms of the GNU General Public License as published by
512- the Free Software Foundation; either version 2 of the License, or
513- (at your option) any later version.
514-
515- This program is distributed in the hope that it will be useful,
516- but WITHOUT ANY WARRANTY; without even the implied warranty of
517- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
518- GNU General Public License for more details.
519-
520- You should have received a copy of the GNU General Public License
521- along with this program; if not, write to the Free Software
522- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
523-
524-Also add information on how to contact you by electronic and paper mail.
525-
526-If the program is interactive, make it output a short notice like this
527-when it starts in an interactive mode:
528-
529- Gnomovision version 69, Copyright (C) 19YY NAME OF AUTHOR
530- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
531- This is free software, and you are welcome to redistribute it
532- under certain conditions; type `show c' for details.
533-
534-The hypothetical commands `show w' and `show c' should show the
535-appropriate parts of the General Public License. Of course, the
536-commands you use may be called something other than `show w' and `show
537-c'; they could even be mouse-clicks or menu items--whatever suits your
538-program.
539-
540-You should also get your employer (if you work as a programmer) or your
541-school, if any, to sign a "copyright disclaimer" for the program, if
542-necessary. Here is a sample; alter the names:
543-
544- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
545- `Gnomovision' (which makes passes at compilers) written by James Hacker.
546-
547- SIGNATURE OF TY COON, 1 April 1989
548- Ty Coon, President of Vice
549-
550-This General Public License does not permit incorporating your program
551-into proprietary programs. If your program is a subroutine library,
552-you may consider it more useful to permit linking proprietary
553-applications with the library. If this is what you want to do, use the
554-GNU Library General Public License instead of this License.
555
556=== removed file 'plugin/innobase/COPYING.Sun_Microsystems'
557--- plugin/innobase/COPYING.Sun_Microsystems 2009-08-12 06:25:19 +0000
558+++ plugin/innobase/COPYING.Sun_Microsystems 1970-01-01 00:00:00 +0000
559@@ -1,31 +0,0 @@
560-Portions of this software contain modifications contributed by
561-Sun Microsystems, Inc. These contributions are used with the following
562-license:
563-
564-Copyright (c) 2009, Sun Microsystems, Inc.
565-All rights reserved.
566-
567-Redistribution and use in source and binary forms, with or without
568-modification, are permitted provided that the following conditions
569-are met:
570- * Redistributions of source code must retain the above copyright
571- notice, this list of conditions and the following disclaimer.
572- * Redistributions in binary form must reproduce the above
573- copyright notice, this list of conditions and the following
574- disclaimer in the documentation and/or other materials
575- provided with the distribution.
576- * Neither the name of Sun Microsystems, Inc. nor the names of its
577- contributors may be used to endorse or promote products derived
578- from this software without specific prior written permission.
579-
580-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
581-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
582-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
583-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
584-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
585-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
586-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
587-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
588-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
589-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
590-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
591
592=== modified file 'plugin/innobase/ChangeLog'
593--- plugin/innobase/ChangeLog 2010-11-18 00:53:34 +0000
594+++ plugin/innobase/ChangeLog 2010-12-07 14:26:13 +0000
595@@ -1,3 +1,29 @@
596+2010-09-06 The InnoDB Team
597+ * dict/dict0load.c, innodb_bug53756.test innodb_bug53756.result
598+ Fix Bug #53756 ALTER TABLE ADD PRIMARY KEY affects crash recovery
599+
600+2010-08-24 The InnoDB Team
601+
602+ * handler/ha_innodb.c, dict/dict0dict.c:
603+ Fix Bug #55832 selects crash too easily when innodb_force_recovery>3
604+
605+2010-08-03 The InnoDB Team
606+ * include/dict0dict.h, include/dict0dict.ic, row/row0mysql.c:
607+ Fix bug #54678, InnoDB, TRUNCATE, ALTER, I_S SELECT, crash or deadlock
608+
609+2010-08-03 The InnoDB Team
610+
611+
612+ * include/ut0mem.h, ut/ut0mem.c:
613+ Fix Bug #55627 segv in ut_free pars_lexer_close innobase_shutdown
614+ innodb-use-sys-malloc=0
615+
616+2010-08-01 The InnoDB Team
617+
618+ * handler/ha_innodb.cc
619+ Fix Bug #55382 Assignment with SELECT expressions takes unexpected
620+ S locks in READ COMMITTED
621+
622 2010-07-27 The InnoDB Team
623
624 * include/mem0pool.h, mem/mem0mem.c, mem/mem0pool.c, srv/srv0start.c:
625
626=== modified file 'plugin/innobase/Doxyfile'
627--- plugin/innobase/Doxyfile 2009-08-12 06:25:19 +0000
628+++ plugin/innobase/Doxyfile 2010-12-07 14:26:13 +0000
629@@ -565,7 +565,7 @@
630 # excluded from the INPUT source files. This way you can easily exclude a
631 # subdirectory from a directory tree whose root is specified with the INPUT tag.
632
633-EXCLUDE = ut0auxconf_*
634+EXCLUDE =
635
636 # The EXCLUDE_SYMLINKS tag can be used select whether or not files or
637 # directories that are symbolic links (a Unix filesystem feature) are excluded
638
639=== modified file 'plugin/innobase/btr/btr0btr.c'
640--- plugin/innobase/btr/btr0btr.c 2010-11-17 05:41:53 +0000
641+++ plugin/innobase/btr/btr0btr.c 2010-12-07 14:26:13 +0000
642@@ -603,7 +603,6 @@
643 ulint line, /*!< in: line where called */
644 mtr_t* mtr) /*!< in: mtr */
645 {
646- page_t* page;
647 dtuple_t* tuple;
648 rec_t* user_rec;
649 rec_t* node_ptr;
650@@ -621,7 +620,6 @@
651
652 level = btr_page_get_level(btr_cur_get_page(cursor), mtr);
653
654- page = btr_cur_get_page(cursor);
655 user_rec = btr_cur_get_rec(cursor);
656 ut_a(page_rec_is_user_rec(user_rec));
657 tuple = dict_index_build_node_ptr(index, user_rec, 0, heap, level);
658@@ -1899,7 +1897,6 @@
659 buf_block_t* left_block;
660 buf_block_t* right_block;
661 buf_block_t* insert_block;
662- page_t* insert_page;
663 page_cur_t* page_cursor;
664 rec_t* first_rec;
665 byte* buf = 0; /* remove warning */
666@@ -2155,8 +2152,6 @@
667 insert_block = right_block;
668 }
669
670- insert_page = buf_block_get_frame(insert_block);
671-
672 /* 7. Reposition the cursor for insert and try insertion */
673 page_cursor = btr_cur_get_page_cur(cursor);
674
675@@ -2168,8 +2163,12 @@
676
677 #ifdef UNIV_ZIP_DEBUG
678 {
679+ page_t* insert_page
680+ = buf_block_get_frame(insert_block);
681+
682 page_zip_des_t* insert_page_zip
683 = buf_block_get_page_zip(insert_block);
684+
685 ut_a(!insert_page_zip
686 || page_zip_validate(insert_page_zip, insert_page));
687 }
688@@ -2562,7 +2561,6 @@
689 ulint n_recs;
690 ulint max_ins_size;
691 ulint max_ins_size_reorg;
692- ulint level;
693
694 block = btr_cur_get_block(cursor);
695 page = btr_cur_get_page(cursor);
696@@ -2572,7 +2570,6 @@
697 ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index),
698 MTR_MEMO_X_LOCK));
699 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
700- level = btr_page_get_level(page, mtr);
701 space = dict_index_get_space(index);
702 zip_size = dict_table_zip_size(index->table);
703
704
705=== modified file 'plugin/innobase/btr/btr0cur.c'
706--- plugin/innobase/btr/btr0cur.c 2010-11-19 04:19:46 +0000
707+++ plugin/innobase/btr/btr0cur.c 2010-12-07 14:26:13 +0000
708@@ -1954,7 +1954,6 @@
709 page_t* page;
710 page_zip_des_t* page_zip;
711 rec_t* rec;
712- rec_t* orig_rec;
713 ulint max_size;
714 ulint new_rec_size;
715 ulint old_rec_size;
716@@ -1968,7 +1967,7 @@
717
718 block = btr_cur_get_block(cursor);
719 page = buf_block_get_frame(block);
720- orig_rec = rec = btr_cur_get_rec(cursor);
721+ rec = btr_cur_get_rec(cursor);
722 index = cursor->index;
723 ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table));
724 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
725@@ -3761,9 +3760,10 @@
726 Marks not updated extern fields as not-owned by this record. The ownership
727 is transferred to the updated record which is inserted elsewhere in the
728 index tree. In purge only the owner of externally stored field is allowed
729-to free the field. */
730+to free the field.
731+@return TRUE if BLOB ownership was transferred */
732 UNIV_INTERN
733-void
734+ibool
735 btr_cur_mark_extern_inherited_fields(
736 /*=================================*/
737 page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
738@@ -3777,13 +3777,14 @@
739 ulint n;
740 ulint j;
741 ulint i;
742+ ibool change_ownership = FALSE;
743
744 ut_ad(rec_offs_validate(rec, NULL, offsets));
745 ut_ad(!rec_offs_comp(offsets) || !rec_get_node_ptr_flag(rec));
746
747 if (!rec_offs_any_extern(offsets)) {
748
749- return;
750+ return(FALSE);
751 }
752
753 n = rec_offs_n_fields(offsets);
754@@ -3806,10 +3807,14 @@
755
756 btr_cur_set_ownership_of_extern_field(
757 page_zip, rec, index, offsets, i, FALSE, mtr);
758+
759+ change_ownership = TRUE;
760 updated:
761 ;
762 }
763 }
764+
765+ return(change_ownership);
766 }
767
768 /*******************************************************************//**
769@@ -4557,12 +4562,17 @@
770 }
771
772 for (;;) {
773+#ifdef UNIV_SYNC_DEBUG
774 buf_block_t* rec_block;
775+#endif /* UNIV_SYNC_DEBUG */
776 buf_block_t* ext_block;
777
778 mtr_start(&mtr);
779
780- rec_block = buf_page_get(page_get_space_id(
781+#ifdef UNIV_SYNC_DEBUG
782+ rec_block =
783+#endif /* UNIV_SYNC_DEBUG */
784+ buf_page_get(page_get_space_id(
785 page_align(field_ref)),
786 rec_zip_size,
787 page_get_page_no(
788
789=== modified file 'plugin/innobase/btr/btr0pcur.c'
790--- plugin/innobase/btr/btr0pcur.c 2010-10-15 05:14:56 +0000
791+++ plugin/innobase/btr/btr0pcur.c 2010-12-07 14:26:13 +0000
792@@ -452,7 +452,6 @@
793 mtr_t* mtr) /*!< in: mtr */
794 {
795 ulint prev_page_no;
796- ulint space;
797 page_t* page;
798 buf_block_t* prev_block;
799 ulint latch_mode;
800@@ -488,7 +487,6 @@
801 page = btr_pcur_get_page(cursor);
802
803 prev_page_no = btr_page_get_prev(page, mtr);
804- space = buf_block_get_space(btr_pcur_get_block(cursor));
805
806 if (prev_page_no == FIL_NULL) {
807 } else if (btr_pcur_is_before_first_on_page(cursor)) {
808
809=== modified file 'plugin/innobase/btr/btr0sea.c'
810--- plugin/innobase/btr/btr0sea.c 2010-11-19 04:18:09 +0000
811+++ plugin/innobase/btr/btr0sea.c 2010-12-07 14:26:13 +0000
812@@ -1502,7 +1502,6 @@
813 rec_t* rec;
814 ulint fold;
815 index_id_t index_id;
816- ibool found;
817 ulint offsets_[REC_OFFS_NORMAL_SIZE];
818 mem_heap_t* heap = NULL;
819 rec_offs_init(offsets_);
820@@ -1535,7 +1534,7 @@
821 }
822 rw_lock_x_lock(&btr_search_latch);
823
824- found = ha_search_and_delete_if_found(table, fold, rec);
825+ ha_search_and_delete_if_found(table, fold, rec);
826
827 rw_lock_x_unlock(&btr_search_latch);
828 }
829
830=== modified file 'plugin/innobase/buf/buf0flu.c'
831--- plugin/innobase/buf/buf0flu.c 2010-11-19 04:18:08 +0000
832+++ plugin/innobase/buf/buf0flu.c 2010-12-07 14:26:13 +0000
833@@ -131,12 +131,17 @@
834 /*============================*/
835 buf_page_t* bpage) /*!< in: bpage to be removed. */
836 {
837+#ifdef UNIV_DEBUG
838 ibool ret = FALSE;
839+#endif /* UNIV_DEBUG */
840 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
841
842 ut_ad(buf_flush_list_mutex_own(buf_pool));
843
844- ret = rbt_delete(buf_pool->flush_rbt, &bpage);
845+#ifdef UNIV_DEBUG
846+ ret =
847+#endif /* UNIV_DEBUG */
848+ rbt_delete(buf_pool->flush_rbt, &bpage);
849 ut_ad(ret);
850 }
851
852
853=== modified file 'plugin/innobase/dict/dict0crea.c'
854--- plugin/innobase/dict/dict0crea.c 2010-11-17 05:41:53 +0000
855+++ plugin/innobase/dict/dict0crea.c 2010-12-07 14:26:13 +0000
856@@ -627,7 +627,6 @@
857 {
858 dict_index_t* index;
859 dict_table_t* sys_indexes;
860- dict_table_t* table;
861 dtuple_t* search_tuple;
862 ulint zip_size;
863 btr_pcur_t pcur;
864@@ -636,7 +635,6 @@
865 ut_ad(mutex_own(&(dict_sys->mutex)));
866
867 index = node->index;
868- table = node->table;
869
870 sys_indexes = dict_sys->sys_indexes;
871
872
873=== modified file 'plugin/innobase/dict/dict0dict.c'
874--- plugin/innobase/dict/dict0dict.c 2010-11-17 05:41:53 +0000
875+++ plugin/innobase/dict/dict0dict.c 2010-12-07 14:26:13 +0000
876@@ -578,8 +578,7 @@
877 {
878 dict_table_t* table;
879
880- if (table_id <= DICT_FIELDS_ID
881- || trx->dict_operation_lock_mode == RW_X_LATCH) {
882+ if (trx->dict_operation_lock_mode == RW_X_LATCH) {
883
884 /* Note: An X latch implies that the transaction
885 already owns the dictionary mutex. */
886@@ -4205,7 +4204,6 @@
887 dictionary mutex */
888 {
889 dict_index_t* index;
890- ulint size;
891 ulint sum_of_index_sizes = 0;
892
893 if (table->ibd_file_missing) {
894@@ -4220,14 +4218,6 @@
895 return;
896 }
897
898- /* If we have set a high innodb_force_recovery level, do not calculate
899- statistics, as a badly corrupted index can cause a crash in it. */
900-
901- if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
902-
903- return;
904- }
905-
906 /* Find out the sizes of the indexes and how many different values
907 for the key they approximately have */
908
909@@ -4239,26 +4229,48 @@
910 return;
911 }
912
913- while (index) {
914- size = btr_get_size(index, BTR_TOTAL_SIZE);
915-
916- index->stat_index_size = size;
917-
918- sum_of_index_sizes += size;
919-
920- size = btr_get_size(index, BTR_N_LEAF_PAGES);
921-
922- if (size == 0) {
923- /* The root node of the tree is a leaf */
924- size = 1;
925+
926+ do {
927+ if (UNIV_LIKELY
928+ (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE
929+ || (srv_force_recovery < SRV_FORCE_NO_LOG_REDO
930+ && dict_index_is_clust(index)))) {
931+ ulint size;
932+ size = btr_get_size(index, BTR_TOTAL_SIZE);
933+
934+ index->stat_index_size = size;
935+
936+ sum_of_index_sizes += size;
937+
938+ size = btr_get_size(index, BTR_N_LEAF_PAGES);
939+
940+ if (size == 0) {
941+ /* The root node of the tree is a leaf */
942+ size = 1;
943+ }
944+
945+ index->stat_n_leaf_pages = size;
946+
947+ btr_estimate_number_of_different_key_vals(index);
948+ } else {
949+ /* If we have set a high innodb_force_recovery
950+ level, do not calculate statistics, as a badly
951+ corrupted index can cause a crash in it.
952+ Initialize some bogus index cardinality
953+ statistics, so that the data can be queried in
954+ various means, also via secondary indexes. */
955+ ulint i;
956+
957+ sum_of_index_sizes++;
958+ index->stat_index_size = index->stat_n_leaf_pages = 1;
959+
960+ for (i = dict_index_get_n_unique(index); i; ) {
961+ index->stat_n_diff_key_vals[i--] = 1;
962+ }
963 }
964
965- index->stat_n_leaf_pages = size;
966-
967- btr_estimate_number_of_different_key_vals(index);
968-
969 index = dict_table_get_next_index(index);
970- }
971+ } while (index);
972
973 index = dict_table_get_first_index(table);
974
975@@ -4441,7 +4453,6 @@
976 {
977 ib_int64_t n_vals;
978 ulint i;
979- const char* type_string;
980
981 ut_ad(mutex_own(&(dict_sys->mutex)));
982
983@@ -4456,14 +4467,6 @@
984
985 dict_index_stat_mutex_exit(index);
986
987- if (dict_index_is_clust(index)) {
988- type_string = "clustered index";
989- } else if (dict_index_is_unique(index)) {
990- type_string = "unique index";
991- } else {
992- type_string = "secondary index";
993- }
994-
995 fprintf(stderr,
996 " INDEX: name %s, id %llu, fields %lu/%lu,"
997 " uniq %lu, type %lu\n"
998
999=== modified file 'plugin/innobase/dict/dict0load.c'
1000--- plugin/innobase/dict/dict0load.c 2010-12-02 07:54:12 +0000
1001+++ plugin/innobase/dict/dict0load.c 2010-12-07 14:26:13 +0000
1002@@ -1799,17 +1799,28 @@
1003
1004 err = dict_load_indexes(table, heap);
1005
1006+ /* Initialize table foreign_child value. Its value could be
1007+ changed when dict_load_foreigns() is called below */
1008+ table->fk_max_recusive_level = 0;
1009+
1010 /* If the force recovery flag is set, we open the table irrespective
1011 of the error condition, since the user may want to dump data from the
1012 clustered index. However we load the foreign key information only if
1013 all indexes were loaded. */
1014 if (!cached) {
1015 } else if (err == DB_SUCCESS) {
1016- err = dict_load_foreigns(table->name, TRUE);
1017+ err = dict_load_foreigns(table->name, TRUE, TRUE);
1018+
1019+ if (err != DB_SUCCESS) {
1020+ dict_table_remove_from_cache(table);
1021+ table = NULL;
1022+ }
1023 } else if (!srv_force_recovery) {
1024 dict_table_remove_from_cache(table);
1025 table = NULL;
1026 }
1027+
1028+ table->fk_max_recusive_level = 0;
1029 #if 0
1030 if (err != DB_SUCCESS && table != NULL) {
1031
1032@@ -1863,6 +1874,8 @@
1033
1034 ut_ad(mutex_own(&(dict_sys->mutex)));
1035
1036+ table = NULL;
1037+
1038 /* NOTE that the operation of this function is protected by
1039 the dictionary mutex, and therefore no deadlocks can occur
1040 with other dictionary operations. */
1041@@ -1889,15 +1902,17 @@
1042 BTR_SEARCH_LEAF, &pcur, &mtr);
1043 rec = btr_pcur_get_rec(&pcur);
1044
1045- if (!btr_pcur_is_on_user_rec(&pcur)
1046- || rec_get_deleted_flag(rec, 0)) {
1047+ if (!btr_pcur_is_on_user_rec(&pcur)) {
1048 /* Not found */
1049-
1050- btr_pcur_close(&pcur);
1051- mtr_commit(&mtr);
1052- mem_heap_free(heap);
1053-
1054- return(NULL);
1055+ goto func_exit;
1056+ }
1057+
1058+ /* Find the first record that is not delete marked */
1059+ while (rec_get_deleted_flag(rec, 0)) {
1060+ if (!btr_pcur_move_to_next_user_rec(&pcur, &mtr)) {
1061+ goto func_exit;
1062+ }
1063+ rec = btr_pcur_get_rec(&pcur);
1064 }
1065
1066 /*---------------------------------------------------*/
1067@@ -1910,12 +1925,7 @@
1068
1069 /* Check if the table id in record is the one searched for */
1070 if (table_id != mach_read_from_8(field)) {
1071-
1072- btr_pcur_close(&pcur);
1073- mtr_commit(&mtr);
1074- mem_heap_free(heap);
1075-
1076- return(NULL);
1077+ goto func_exit;
1078 }
1079
1080 /* Now we get the table name from the record */
1081@@ -1923,7 +1933,7 @@
1082 /* Load the table definition to memory */
1083 table = dict_load_table(mem_heap_strdupl(heap, (char*) field, len),
1084 TRUE);
1085-
1086+func_exit:
1087 btr_pcur_close(&pcur);
1088 mtr_commit(&mtr);
1089 mem_heap_free(heap);
1090@@ -2033,8 +2043,12 @@
1091 /*==============*/
1092 const char* id, /*!< in: foreign constraint id as a
1093 null-terminated string */
1094- ibool check_charsets)
1095+ ibool check_charsets,
1096 /*!< in: TRUE=check charset compatibility */
1097+ ibool check_recursive)
1098+ /*!< in: Whether to record the foreign table
1099+ parent count to avoid unlimited recursive
1100+ load of chained foreign tables */
1101 {
1102 dict_foreign_t* foreign;
1103 dict_table_t* sys_foreign;
1104@@ -2048,6 +2062,8 @@
1105 ulint len;
1106 ulint n_fields_and_type;
1107 mtr_t mtr;
1108+ dict_table_t* for_table;
1109+ dict_table_t* ref_table;
1110
1111 ut_ad(mutex_own(&(dict_sys->mutex)));
1112
1113@@ -2132,11 +2148,54 @@
1114
1115 dict_load_foreign_cols(id, foreign);
1116
1117- /* If the foreign table is not yet in the dictionary cache, we
1118- have to load it so that we are able to make type comparisons
1119- in the next function call. */
1120-
1121- dict_table_get_low(foreign->foreign_table_name);
1122+ ref_table = dict_table_check_if_in_cache_low(
1123+ foreign->referenced_table_name);
1124+
1125+ /* We could possibly wind up in a deep recursive calls if
1126+ we call dict_table_get_low() again here if there
1127+ is a chain of tables concatenated together with
1128+ foreign constraints. In such case, each table is
1129+ both a parent and child of the other tables, and
1130+ act as a "link" in such table chains.
1131+ To avoid such scenario, we would need to check the
1132+ number of ancesters the current table has. If that
1133+ exceeds DICT_FK_MAX_CHAIN_LEN, we will stop loading
1134+ the child table.
1135+ Foreign constraints are loaded in a Breath First fashion,
1136+ that is, the index on FOR_NAME is scanned first, and then
1137+ index on REF_NAME. So foreign constrains in which
1138+ current table is a child (foreign table) are loaded first,
1139+ and then those constraints where current table is a
1140+ parent (referenced) table.
1141+ Thus we could check the parent (ref_table) table's
1142+ reference count (fk_max_recusive_level) to know how deep the
1143+ recursive call is. If the parent table (ref_table) is already
1144+ loaded, and its fk_max_recusive_level is larger than
1145+ DICT_FK_MAX_CHAIN_LEN, we will stop the recursive loading
1146+ by skipping loading the child table. It will not affect foreign
1147+ constraint check for DMLs since child table will be loaded
1148+ at that time for the constraint check. */
1149+ if (!ref_table
1150+ || ref_table->fk_max_recusive_level < DICT_FK_MAX_RECURSIVE_LOAD) {
1151+
1152+ /* If the foreign table is not yet in the dictionary cache, we
1153+ have to load it so that we are able to make type comparisons
1154+ in the next function call. */
1155+
1156+ for_table = dict_table_get_low(foreign->foreign_table_name);
1157+
1158+ if (for_table && ref_table && check_recursive) {
1159+ /* This is to record the longest chain of ancesters
1160+ this table has, if the parent has more ancesters
1161+ than this table has, record it after add 1 (for this
1162+ parent */
1163+ if (ref_table->fk_max_recusive_level
1164+ >= for_table->fk_max_recusive_level) {
1165+ for_table->fk_max_recusive_level =
1166+ ref_table->fk_max_recusive_level + 1;
1167+ }
1168+ }
1169+ }
1170
1171 /* Note that there may already be a foreign constraint object in
1172 the dictionary cache for this constraint: then the following
1173@@ -2161,6 +2220,8 @@
1174 dict_load_foreigns(
1175 /*===============*/
1176 const char* table_name, /*!< in: table name */
1177+ ibool check_recursive,/*!< in: Whether to check recursive
1178+ load of tables chained by FK */
1179 ibool check_charsets) /*!< in: TRUE=check charset
1180 compatibility */
1181 {
1182@@ -2262,7 +2323,7 @@
1183
1184 /* Load the foreign constraint definition to the dictionary cache */
1185
1186- err = dict_load_foreign(id, check_charsets);
1187+ err = dict_load_foreign(id, check_charsets, check_recursive);
1188
1189 if (err != DB_SUCCESS) {
1190 btr_pcur_close(&pcur);
1191@@ -2290,6 +2351,11 @@
1192
1193 mtr_start(&mtr);
1194
1195+ /* Switch to scan index on REF_NAME, fk_max_recusive_level
1196+ already been updated when scanning FOR_NAME index, no need to
1197+ update again */
1198+ check_recursive = FALSE;
1199+
1200 goto start_load;
1201 }
1202
1203
1204=== modified file 'plugin/innobase/eval/eval0eval.c'
1205--- plugin/innobase/eval/eval0eval.c 2010-10-02 21:15:42 +0000
1206+++ plugin/innobase/eval/eval0eval.c 2010-12-07 14:26:13 +0000
1207@@ -384,18 +384,13 @@
1208 /*==========*/
1209 func_node_t* func_node) /*!< in: function node */
1210 {
1211- que_node_t* arg1;
1212- que_node_t* arg2;
1213 sym_node_t* cursor;
1214 sel_node_t* sel_node;
1215 ibool ibool_val;
1216
1217- arg1 = func_node->args;
1218- arg2 = que_node_get_next(arg1);
1219-
1220 ut_ad(func_node->func == PARS_NOTFOUND_TOKEN);
1221
1222- cursor = arg1;
1223+ cursor = func_node->args;
1224
1225 ut_ad(que_node_get_type(cursor) == QUE_NODE_SYMBOL);
1226
1227
1228=== modified file 'plugin/innobase/handler/ha_innodb.cc'
1229--- plugin/innobase/handler/ha_innodb.cc 2010-12-05 07:48:35 +0000
1230+++ plugin/innobase/handler/ha_innodb.cc 2010-12-07 14:26:13 +0000
1231@@ -1036,6 +1036,18 @@
1232 case DB_INTERRUPTED:
1233 my_error(ER_QUERY_INTERRUPTED, MYF(0));
1234 /* fall through */
1235+
1236+ case DB_FOREIGN_EXCEED_MAX_CASCADE:
1237+ push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1238+ HA_ERR_ROW_IS_REFERENCED,
1239+ "InnoDB: Cannot delete/update "
1240+ "rows with cascading foreign key "
1241+ "constraints that exceed max "
1242+ "depth of %d. Please "
1243+ "drop extra constraints and try "
1244+ "again", DICT_FK_MAX_RECURSIVE_LOAD);
1245+ /* fall through */
1246+
1247 case DB_ERROR:
1248 default:
1249 return(-1); /* unspecified error */
1250@@ -3286,12 +3298,18 @@
1251 err = row_search_max_autoinc(index, col_name, &read_auto_inc);
1252
1253 switch (err) {
1254- case DB_SUCCESS:
1255+ case DB_SUCCESS: {
1256+ uint64_t col_max_value;
1257+
1258+ col_max_value = innobase_get_int_col_max_value(field);
1259+
1260 /* At the this stage we do not know the increment
1261- or the offset, so use a default increment of 1. */
1262- auto_inc = read_auto_inc + 1;
1263+ nor the offset, so use a default increment of 1. */
1264+
1265+ auto_inc = innobase_next_autoinc(read_auto_inc, 1, 1, col_max_value);
1266+
1267 break;
1268-
1269+ }
1270 case DB_RECORD_NOT_FOUND:
1271 ut_print_timestamp(stderr);
1272 fprintf(stderr, " InnoDB: MySQL and InnoDB data "
1273@@ -3569,8 +3587,6 @@
1274 dict_table_get_format(prebuilt->table));
1275 }
1276
1277- info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
1278-
1279 /* Only if the table has an AUTOINC column. */
1280 if (prebuilt->table != NULL && getTable()->found_next_number_field != NULL) {
1281
1282@@ -3588,6 +3604,8 @@
1283 dict_table_autoinc_unlock(prebuilt->table);
1284 }
1285
1286+ info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
1287+
1288 return(0);
1289 }
1290
1291@@ -7106,24 +7124,12 @@
1292 dict_index_t* index;
1293 ha_rows rec_per_key;
1294 ib_int64_t n_rows;
1295- ulong j;
1296- ulong i;
1297 os_file_stat_t stat_info;
1298
1299 /* If we are forcing recovery at a high level, we will suppress
1300 statistics calculation on tables, because that may crash the
1301 server if an index is badly corrupted. */
1302
1303- if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
1304-
1305- /* We return success (0) instead of HA_ERR_CRASHED,
1306- because we want MySQL to process this query and not
1307- stop, like it would do if it received the error code
1308- HA_ERR_CRASHED. */
1309-
1310- return(0);
1311- }
1312-
1313 /* We do not know if MySQL can call this function before calling
1314 external_lock(). To be safe, update the session of the current table
1315 handle. */
1316@@ -7215,12 +7221,18 @@
1317 acquiring latches inside InnoDB, we do not call it if we
1318 are asked by MySQL to avoid locking. Another reason to
1319 avoid the call is that it uses quite a lot of CPU.
1320- See Bug#38185.
1321- We do not update delete_length if no locking is requested
1322- so the "old" value can remain. delete_length is initialized
1323- to 0 in the ha_statistics' constructor. */
1324- if (!(flag & HA_STATUS_NO_LOCK)) {
1325-
1326+ See Bug#38185. */
1327+ if (flag & HA_STATUS_NO_LOCK) {
1328+ /* We do not update delete_length if no
1329+ locking is requested so the "old" value can
1330+ remain. delete_length is initialized to 0 in
1331+ the ha_statistics' constructor. */
1332+ } else if (UNIV_UNLIKELY
1333+ (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE)) {
1334+ /* Avoid accessing the tablespace if
1335+ innodb_crash_recovery is set to a high value. */
1336+ stats.delete_length = 0;
1337+ } else {
1338 /* lock the data dictionary to avoid races with
1339 ibd_file_missing and tablespace_discarded */
1340 row_mysql_lock_data_dictionary(prebuilt->trx);
1341@@ -7266,6 +7278,7 @@
1342 }
1343
1344 if (flag & HA_STATUS_CONST) {
1345+ ulong i;
1346 /* Verify the number of index in InnoDB and MySQL
1347 matches up. If prebuilt->clust_index_was_generated
1348 holds, InnoDB defines GEN_CLUST_INDEX internally */
1349@@ -7281,6 +7294,7 @@
1350 }
1351
1352 for (i = 0; i < getTable()->getShare()->sizeKeys(); i++) {
1353+ ulong j;
1354 /* We could get index quickly through internal
1355 index mapping with the index translation table.
1356 The identity of index (match up index name with
1357@@ -7346,6 +7360,10 @@
1358 }
1359 }
1360
1361+ if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
1362+ goto func_exit;
1363+ }
1364+
1365 if (flag & HA_STATUS_ERRKEY) {
1366 const dict_index_t* err_index;
1367
1368@@ -7367,6 +7385,7 @@
1369 stats.auto_increment_value = innobase_peek_autoinc();
1370 }
1371
1372+func_exit:
1373 prebuilt->trx->op_info = (char*)"";
1374
1375 return(0);
1376@@ -8067,7 +8086,7 @@
1377 {
1378 trx_t* trx;
1379 static const char truncated_msg[] = "... truncated...\n";
1380- const long MAX_STATUS_SIZE = 64000;
1381+ const long MAX_STATUS_SIZE = 1048576;
1382 ulint trx_list_start = ULINT_UNDEFINED;
1383 ulint trx_list_end = ULINT_UNDEFINED;
1384
1385@@ -8096,6 +8115,7 @@
1386
1387 if (flen > MAX_STATUS_SIZE) {
1388 usable_len = MAX_STATUS_SIZE;
1389+ srv_truncated_status_writes++;
1390 } else {
1391 usable_len = flen;
1392 }
1393@@ -8131,12 +8151,9 @@
1394
1395 mutex_exit(&srv_monitor_file_mutex);
1396
1397- bool result = FALSE;
1398+ stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
1399+ STRING_WITH_LEN(""), str, flen);
1400
1401- if (stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
1402- STRING_WITH_LEN(""), str, flen)) {
1403- result= TRUE;
1404- }
1405 free(str);
1406
1407 return(FALSE);
1408@@ -8485,7 +8502,8 @@
1409 && (sql_command == SQLCOM_INSERT_SELECT
1410 || sql_command == SQLCOM_REPLACE_SELECT
1411 || sql_command == SQLCOM_UPDATE
1412- || sql_command == SQLCOM_CREATE_TABLE)) {
1413+ || sql_command == SQLCOM_CREATE_TABLE
1414+ || sql_command == SQLCOM_SET_OPTION)) {
1415
1416 /* If we either have innobase_locks_unsafe_for_binlog
1417 option set or this session is using READ COMMITTED
1418@@ -8493,9 +8511,9 @@
1419 is not set to serializable and MySQL is doing
1420 INSERT INTO...SELECT or REPLACE INTO...SELECT
1421 or UPDATE ... = (SELECT ...) or CREATE ...
1422- SELECT... without FOR UPDATE or IN SHARE
1423- MODE in select, then we use consistent read
1424- for select. */
1425+ SELECT... or SET ... = (SELECT ...) without
1426+ FOR UPDATE or IN SHARE MODE in select,
1427+ then we use consistent read for select. */
1428
1429 prebuilt->select_lock_type = LOCK_NONE;
1430 prebuilt->stored_select_lock_type = LOCK_NONE;
1431@@ -8583,7 +8601,7 @@
1432 }
1433
1434 /*******************************************************************//**
1435-This function reads the global auto-inc counter. It doesn't use the
1436+This function reads the global auto-inc counter. It doesn't use the
1437 AUTOINC lock even if the lock mode is set to TRADITIONAL.
1438 @return the autoinc value */
1439 UNIV_INTERN
1440@@ -8603,7 +8621,11 @@
1441
1442 auto_inc = dict_table_autoinc_read(innodb_table);
1443
1444- ut_a(auto_inc > 0);
1445+ if (auto_inc == 0) {
1446+ ut_print_timestamp(stderr);
1447+ fprintf(stderr, " InnoDB: AUTOINC next value generation "
1448+ "is disabled for '%s'\n", innodb_table->name);
1449+ }
1450
1451 dict_table_autoinc_unlock(innodb_table);
1452
1453
1454=== modified file 'plugin/innobase/ibuf/ibuf0ibuf.c'
1455--- plugin/innobase/ibuf/ibuf0ibuf.c 2010-11-19 04:18:11 +0000
1456+++ plugin/innobase/ibuf/ibuf0ibuf.c 2010-12-07 14:26:13 +0000
1457@@ -1297,12 +1297,11 @@
1458 const rec_t* rec) /*!< in: ibuf record */
1459 {
1460 ulint len;
1461- const byte* field;
1462
1463 ut_ad(ibuf_inside());
1464 ut_ad(rec_get_n_fields_old(rec) > 2);
1465
1466- field = rec_get_nth_field_old(rec, 1, &len);
1467+ (void) rec_get_nth_field_old(rec, 1, &len);
1468
1469 if (len > 1) {
1470 /* This is a < 4.1.x format record */
1471@@ -3779,17 +3778,11 @@
1472 rec = page_rec_get_next(page_get_infimum_rec(page));
1473
1474 if (page_rec_is_supremum(rec)) {
1475- /* Empty pages can result from buffered delete operations.
1476- The first record from the free list can be used to find the
1477- father node. */
1478- rec = page_header_get_ptr(page, PAGE_FREE);
1479- if (UNIV_UNLIKELY(rec == NULL)) {
1480- fputs("InnoDB: Trying to insert a record from"
1481- " the insert buffer to an index page\n"
1482- "InnoDB: but the index page is empty!\n",
1483- stderr);
1484- goto dump;
1485- }
1486+ fputs("InnoDB: Trying to insert a record from"
1487+ " the insert buffer to an index page\n"
1488+ "InnoDB: but the index page is empty!\n",
1489+ stderr);
1490+ goto dump;
1491 }
1492
1493 if (UNIV_UNLIKELY(rec_get_n_fields(rec, index)
1494
1495=== modified file 'plugin/innobase/include/btr0cur.h'
1496--- plugin/innobase/include/btr0cur.h 2010-11-19 04:19:46 +0000
1497+++ plugin/innobase/include/btr0cur.h 2010-12-07 14:26:13 +0000
1498@@ -456,9 +456,10 @@
1499 Marks not updated extern fields as not-owned by this record. The ownership
1500 is transferred to the updated record which is inserted elsewhere in the
1501 index tree. In purge only the owner of externally stored field is allowed
1502-to free the field. */
1503+to free the field.
1504+@return TRUE if BLOB ownership was transferred */
1505 UNIV_INTERN
1506-void
1507+ibool
1508 btr_cur_mark_extern_inherited_fields(
1509 /*=================================*/
1510 page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
1511
1512=== modified file 'plugin/innobase/include/buf0flu.h'
1513--- plugin/innobase/include/buf0flu.h 2010-11-11 06:56:57 +0000
1514+++ plugin/innobase/include/buf0flu.h 2010-12-07 14:26:13 +0000
1515@@ -228,8 +228,8 @@
1516 sweep). */
1517 #define BUF_FLUSH_FREE_BLOCK_MARGIN(b) (5 + BUF_READ_AHEAD_AREA(b))
1518 /** Extra margin to apply above BUF_FLUSH_FREE_BLOCK_MARGIN */
1519-#define BUF_FLUSH_EXTRA_MARGIN(b) (BUF_FLUSH_FREE_BLOCK_MARGIN(b) / 4 \
1520- + 100)
1521+#define BUF_FLUSH_EXTRA_MARGIN(b) ((BUF_FLUSH_FREE_BLOCK_MARGIN(b) / 4 \
1522+ + 100) / srv_buf_pool_instances)
1523 #endif /* !UNIV_HOTBACKUP */
1524
1525 #ifndef UNIV_NONINL
1526
1527=== modified file 'plugin/innobase/include/db0err.h'
1528--- plugin/innobase/include/db0err.h 2010-11-16 06:01:25 +0000
1529+++ plugin/innobase/include/db0err.h 2010-12-07 14:26:13 +0000
1530@@ -101,6 +101,9 @@
1531 requested but this storage does not
1532 exist itself or the stats for a given
1533 table do not exist */
1534+ DB_FOREIGN_EXCEED_MAX_CASCADE, /* Foreign key constraint related
1535+ cascading delete/update exceeds
1536+ maximum allowed depth */
1537
1538 /* The following are partial failure codes */
1539 DB_FAIL = 1000,
1540
1541=== modified file 'plugin/innobase/include/dict0dict.h'
1542--- plugin/innobase/include/dict0dict.h 2010-11-17 05:52:09 +0000
1543+++ plugin/innobase/include/dict0dict.h 2010-12-07 14:26:13 +0000
1544@@ -699,6 +699,22 @@
1545 dict_table_zip_size(
1546 /*================*/
1547 const dict_table_t* table); /*!< in: table */
1548+/*********************************************************************//**
1549+Obtain exclusive locks on all index trees of the table. This is to prevent
1550+accessing index trees while InnoDB is updating internal metadata for
1551+operations such as truncate tables. */
1552+UNIV_INLINE
1553+void
1554+dict_table_x_lock_indexes(
1555+/*======================*/
1556+ dict_table_t* table); /*!< in: table */
1557+/*********************************************************************//**
1558+Release the exclusive locks on all index tree. */
1559+UNIV_INLINE
1560+void
1561+dict_table_x_unlock_indexes(
1562+/*========================*/
1563+ dict_table_t* table); /*!< in: table */
1564 /********************************************************************//**
1565 Checks if a column is in the ordering columns of the clustered index of a
1566 table. Column prefixes are treated like whole columns.
1567
1568=== modified file 'plugin/innobase/include/dict0dict.ic'
1569--- plugin/innobase/include/dict0dict.ic 2010-11-17 05:52:09 +0000
1570+++ plugin/innobase/include/dict0dict.ic 2010-12-07 14:26:13 +0000
1571@@ -491,6 +491,48 @@
1572 return(dict_table_flags_to_zip_size(table->flags));
1573 }
1574
1575+/*********************************************************************//**
1576+Obtain exclusive locks on all index trees of the table. This is to prevent
1577+accessing index trees while InnoDB is updating internal metadata for
1578+operations such as truncate tables. */
1579+UNIV_INLINE
1580+void
1581+dict_table_x_lock_indexes(
1582+/*======================*/
1583+ dict_table_t* table) /*!< in: table */
1584+{
1585+ dict_index_t* index;
1586+
1587+ ut_a(table);
1588+ ut_ad(mutex_own(&(dict_sys->mutex)));
1589+
1590+ /* Loop through each index of the table and lock them */
1591+ for (index = dict_table_get_first_index(table);
1592+ index != NULL;
1593+ index = dict_table_get_next_index(index)) {
1594+ rw_lock_x_lock(dict_index_get_lock(index));
1595+ }
1596+}
1597+
1598+/*********************************************************************//**
1599+Release the exclusive locks on all index tree. */
1600+UNIV_INLINE
1601+void
1602+dict_table_x_unlock_indexes(
1603+/*========================*/
1604+ dict_table_t* table) /*!< in: table */
1605+{
1606+ dict_index_t* index;
1607+
1608+ ut_a(table);
1609+ ut_ad(mutex_own(&(dict_sys->mutex)));
1610+
1611+ for (index = dict_table_get_first_index(table);
1612+ index != NULL;
1613+ index = dict_table_get_next_index(index)) {
1614+ rw_lock_x_unlock(dict_index_get_lock(index));
1615+ }
1616+}
1617 /********************************************************************//**
1618 Gets the number of fields in the internal representation of an index,
1619 including fields added by the dictionary system.
1620
1621=== modified file 'plugin/innobase/include/dict0load.h'
1622--- plugin/innobase/include/dict0load.h 2010-12-02 07:54:12 +0000
1623+++ plugin/innobase/include/dict0load.h 2010-12-07 14:26:13 +0000
1624@@ -200,6 +200,8 @@
1625 dict_load_foreigns(
1626 /*===============*/
1627 const char* table_name, /*!< in: table name */
1628+ ibool check_recursive,/*!< in: Whether to check recursive
1629+ load of tables chained by FK */
1630 ibool check_charsets);/*!< in: TRUE=check charsets
1631 compatibility */
1632 /********************************************************************//**
1633
1634=== modified file 'plugin/innobase/include/dict0mem.h'
1635--- plugin/innobase/include/dict0mem.h 2010-11-17 05:52:09 +0000
1636+++ plugin/innobase/include/dict0mem.h 2010-12-07 14:26:13 +0000
1637@@ -116,6 +116,21 @@
1638 in table->flags. */
1639 /* @} */
1640
1641+/** Tables could be chained together with Foreign key constraint. When
1642+first load the parent table, we would load all of its descedents.
1643+This could result in rescursive calls and out of stack error eventually.
1644+DICT_FK_MAX_RECURSIVE_LOAD defines the maximum number of recursive loads,
1645+when exceeded, the child table will not be loaded. It will be loaded when
1646+the foreign constraint check needs to be run. */
1647+#define DICT_FK_MAX_RECURSIVE_LOAD 255
1648+
1649+/** Similarly, when tables are chained together with foreign key constraints
1650+with on cascading delete/update clause, delete from parent table could
1651+result in recursive cascading calls. This defines the maximum number of
1652+such cascading deletes/updates allowed. When exceeded, the delete from
1653+parent table will fail, and user has to drop excessive foreign constraint
1654+before proceeds. */
1655+#define FK_MAX_CASCADE_DEL 255
1656
1657 /**********************************************************************//**
1658 Creates a table memory object.
1659@@ -469,6 +484,12 @@
1660 NOT allowed until this count gets to zero;
1661 MySQL does NOT itself check the number of
1662 open handles at drop */
1663+ unsigned fk_max_recusive_level:8;
1664+ /*!< maximum recursive level we support when
1665+ loading tables chained together with FK
1666+ constraints. If exceeds this level, we will
1667+ stop loading child table into memory along with
1668+ its parent table */
1669 ulint n_foreign_key_checks_running;
1670 /*!< count of how many foreign key check
1671 operations are currently being performed
1672
1673=== modified file 'plugin/innobase/include/os0sync.h'
1674--- plugin/innobase/include/os0sync.h 2010-11-17 06:08:58 +0000
1675+++ plugin/innobase/include/os0sync.h 2010-12-07 14:26:13 +0000
1676@@ -289,7 +289,7 @@
1677 Returns the old value of *ptr, atomically sets *ptr to new_val */
1678
1679 # define os_atomic_test_and_set_byte(ptr, new_val) \
1680- __sync_lock_test_and_set(ptr, new_val)
1681+ __sync_lock_test_and_set(ptr, (byte) new_val)
1682
1683 #elif defined(HAVE_SOLARIS_ATOMICS)
1684
1685
1686=== modified file 'plugin/innobase/include/que0que.h'
1687--- plugin/innobase/include/que0que.h 2010-11-17 05:41:53 +0000
1688+++ plugin/innobase/include/que0que.h 2010-12-07 14:26:13 +0000
1689@@ -381,6 +381,9 @@
1690 thus far */
1691 ulint lock_state; /*!< lock state of thread (table or
1692 row) */
1693+ ulint fk_cascade_depth; /*!< maximum cascading call depth
1694+ supported for foreign key constraint
1695+ related delete/updates */
1696 };
1697
1698 #define QUE_THR_MAGIC_N 8476583
1699
1700=== modified file 'plugin/innobase/include/srv0srv.h'
1701--- plugin/innobase/include/srv0srv.h 2010-11-17 06:08:58 +0000
1702+++ plugin/innobase/include/srv0srv.h 2010-12-07 14:26:13 +0000
1703@@ -230,6 +230,7 @@
1704 extern ulong srv_spin_wait_delay;
1705 extern ibool srv_priority_boost;
1706
1707+extern ulint srv_truncated_status_writes;
1708
1709 #ifdef UNIV_DEBUG
1710 extern ibool srv_print_thread_releases;
1711@@ -719,11 +720,12 @@
1712 ulint innodb_rows_inserted; /*!< srv_n_rows_inserted */
1713 ulint innodb_rows_updated; /*!< srv_n_rows_updated */
1714 ulint innodb_rows_deleted; /*!< srv_n_rows_deleted */
1715+ ulint innodb_truncated_status_writes; /*!< srv_truncated_status_writes */
1716 };
1717
1718 /** Thread slot in the thread table */
1719 typedef struct srv_slot_struct srv_slot_t;
1720-
1721+
1722 /** Thread table is an array of slots */
1723 typedef srv_slot_t srv_table_t;
1724
1725
1726=== modified file 'plugin/innobase/include/univ.i'
1727--- plugin/innobase/include/univ.i 2010-12-04 09:19:54 +0000
1728+++ plugin/innobase/include/univ.i 2010-12-07 14:26:13 +0000
1729@@ -52,7 +52,7 @@
1730
1731 #define INNODB_VERSION_MAJOR 1
1732 #define INNODB_VERSION_MINOR 1
1733-#define INNODB_VERSION_BUGFIX 2
1734+#define INNODB_VERSION_BUGFIX 3
1735
1736 /* The following is the InnoDB version as shown in
1737 SELECT plugin_version FROM information_schema.plugins;
1738@@ -84,18 +84,6 @@
1739 # define ha_innobase ha_innodb
1740 #endif /* MYSQL_DYNAMIC_PLUGIN */
1741
1742-/* if any of the following macros are not defined we are missing fundamental
1743- * and important symbols
1744- */
1745-#if !defined(HAVE_GCC_ATOMIC_BUILTINS) \
1746- && !defined(HAVE_IB_ATOMIC_PTHREAD_T_GCC) \
1747- && !defined(HAVE_SOLARIS_ATOMICS) \
1748- && !defined(HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS) \
1749- && !defined(SIZEOF_PTHREAD_T) \
1750- && !defined(IB_HAVE_PAUSE_INSTRUCTION)
1751-# error There is a problem in the configure setup
1752-#endif
1753-
1754 #if (defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)) && !defined(MYSQL_SERVER) && !defined(__WIN__)
1755 # undef __WIN__
1756 # define __WIN__
1757
1758=== modified file 'plugin/innobase/include/ut0rbt.h'
1759--- plugin/innobase/include/ut0rbt.h 2010-11-11 06:56:57 +0000
1760+++ plugin/innobase/include/ut0rbt.h 2010-12-07 14:26:13 +0000
1761@@ -53,7 +53,7 @@
1762 /* Red black tree typedefs */
1763 typedef struct ib_rbt_struct ib_rbt_t;
1764 typedef struct ib_rbt_node_struct ib_rbt_node_t;
1765-// FIXME: Iterator is a better name than _bound_
1766+/* FIXME: Iterator is a better name than _bound_ */
1767 typedef struct ib_rbt_bound_struct ib_rbt_bound_t;
1768 typedef void (*ib_rbt_print_node)(const ib_rbt_node_t* node);
1769 typedef int (*ib_rbt_compare)(const void* p1, const void* p2);
1770
1771=== modified file 'plugin/innobase/include/ut0rnd.ic'
1772--- plugin/innobase/include/ut0rnd.ic 2010-11-17 05:41:53 +0000
1773+++ plugin/innobase/include/ut0rnd.ic 2010-12-07 14:26:13 +0000
1774@@ -85,9 +85,6 @@
1775 /*==================*/
1776 {
1777 ulint rnd;
1778- ulint n_bits;
1779-
1780- n_bits = 8 * sizeof(ulint);
1781
1782 ut_rnd_ulint_counter = UT_RND1 * ut_rnd_ulint_counter + UT_RND2;
1783
1784
1785=== modified file 'plugin/innobase/log/log0recv.c'
1786--- plugin/innobase/log/log0recv.c 2010-11-17 05:41:53 +0000
1787+++ plugin/innobase/log/log0recv.c 2010-12-07 14:26:13 +0000
1788@@ -569,10 +569,8 @@
1789 ib_uint64_t start_lsn;
1790 ib_uint64_t end_lsn;
1791 ib_uint64_t recovered_lsn;
1792- ib_uint64_t limit_lsn;
1793
1794 recovered_lsn = recv_sys->recovered_lsn;
1795- limit_lsn = recv_sys->limit_lsn;
1796
1797 /* Read the last recovered log block to the recovery system buffer:
1798 the block is always incomplete */
1799@@ -1659,12 +1657,8 @@
1800
1801 #ifndef UNIV_HOTBACKUP
1802 if (modification_to_page) {
1803- buf_pool_t* buf_pool;
1804-
1805 ut_a(block);
1806
1807- buf_pool = buf_pool_from_block(block);
1808-
1809 log_flush_order_mutex_enter();
1810 buf_flush_recv_note_modification(block, start_lsn, end_lsn);
1811 log_flush_order_mutex_exit();
1812@@ -2908,7 +2902,9 @@
1813 ib_uint64_t old_scanned_lsn;
1814 ib_uint64_t group_scanned_lsn= 0;
1815 ib_uint64_t contiguous_lsn;
1816+#ifdef UNIV_LOG_ARCHIVE
1817 ib_uint64_t archived_lsn;
1818+#endif /* UNIV_LOG_ARCHIVE */
1819 byte* buf;
1820 byte log_hdr_buf[LOG_FILE_HDR_SIZE];
1821 ulint err;
1822@@ -2963,7 +2959,9 @@
1823
1824 checkpoint_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_LSN);
1825 checkpoint_no = mach_read_from_8(buf + LOG_CHECKPOINT_NO);
1826+#ifdef UNIV_LOG_ARCHIVE
1827 archived_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN);
1828+#endif /* UNIV_LOG_ARCHIVE */
1829
1830 /* Read the first log file header to print a note if this is
1831 a recovery from a restored InnoDB Hot Backup */
1832
1833=== modified file 'plugin/innobase/os/os0file.c'
1834--- plugin/innobase/os/os0file.c 2010-12-02 04:04:33 +0000
1835+++ plugin/innobase/os/os0file.c 2010-12-07 14:26:13 +0000
1836@@ -1488,8 +1488,6 @@
1837 int create_flag;
1838 ibool retry;
1839 const char* mode_str = NULL;
1840- const char* type_str = NULL;
1841- const char* purpose_str = NULL;
1842
1843 try_again:
1844 ut_a(name);
1845@@ -1509,26 +1507,9 @@
1846 ut_error;
1847 }
1848
1849- if (type == OS_LOG_FILE) {
1850- type_str = "LOG";
1851- } else if (type == OS_DATA_FILE) {
1852- type_str = "DATA";
1853- } else {
1854- ut_error;
1855- }
1856-
1857- if (purpose == OS_FILE_AIO) {
1858- purpose_str = "AIO";
1859- } else if (purpose == OS_FILE_NORMAL) {
1860- purpose_str = "NORMAL";
1861- } else {
1862- ut_error;
1863- }
1864-
1865-#if 0
1866- fprintf(stderr, "Opening file %s, mode %s, type %s, purpose %s\n",
1867- name, mode_str, type_str, purpose_str);
1868-#endif
1869+ ut_a(type == OS_LOG_FILE || type == OS_DATA_FILE);
1870+ ut_a(purpose == OS_FILE_AIO || purpose == OS_FILE_NORMAL);
1871+
1872 #ifdef O_SYNC
1873 /* We let O_SYNC only affect log files; note that we map O_DSYNC to
1874 O_SYNC because the datasync options seemed to corrupt files in 2001
1875
1876=== modified file 'plugin/innobase/plugin.am'
1877--- plugin/innobase/plugin.am 2010-12-05 04:42:02 +0000
1878+++ plugin/innobase/plugin.am 2010-12-07 14:26:13 +0000
1879@@ -373,11 +373,5 @@
1880 EXTRA_DIST+= \
1881 plugin/innobase/CMakeLists.txt \
1882 plugin/innobase/pars/pars0grm.y \
1883- plugin/innobase/pars/pars0lex.l \
1884- plugin/innobase/ut/ut0auxconf_atomic_pthread_t_gcc.c \
1885- plugin/innobase/ut/ut0auxconf_atomic_pthread_t_solaris.c \
1886- plugin/innobase/ut/ut0auxconf_have_solaris_atomics.c \
1887- plugin/innobase/ut/ut0auxconf_pause.c \
1888- plugin/innobase/ut/ut0auxconf_sizeof_pthread_t.c
1889-
1890+ plugin/innobase/pars/pars0lex.l
1891
1892
1893=== modified file 'plugin/innobase/plugin.ini'
1894--- plugin/innobase/plugin.ini 2010-12-02 00:57:45 +0000
1895+++ plugin/innobase/plugin.ini 2010-12-07 14:26:13 +0000
1896@@ -28,10 +28,9 @@
1897 cflags=${NO_SHADOW} -I$(top_srcdir)/plugin/innobase/include -DBUILD_DRIZZLE
1898 cxxflags=${NO_SHADOW} -I$(top_srcdir)/plugin/innobase/include -DBUILD_DRIZZLE
1899 libs=plugin/innobase/libinnobase.la
1900-extra_dist=COPYING
1901+extra_dist=
1902 COPYING.Google
1903 COPYING.Percona
1904- COPYING.Sun_Microsystems
1905 ChangeLog
1906 Doxyfile
1907 README
1908@@ -55,7 +54,6 @@
1909 mysql-test/innodb_bug39438-master.opt
1910 mysql-test/innodb_bug39438.result
1911 mysql-test/innodb_bug39438.test
1912- ut/ut0auxconf_have_gcc_atomics.c
1913
1914
1915 #cflags=${INNODB_DYNAMIC_CFLAGS} ${NO_SHADOW} -I$(top_srcdir)/storage/innobase/include -DBUILD_DRIZZLE
1916
1917=== modified file 'plugin/innobase/que/que0que.c'
1918--- plugin/innobase/que/que0que.c 2010-11-11 10:38:30 +0000
1919+++ plugin/innobase/que/que0que.c 2010-12-07 14:26:13 +0000
1920@@ -1283,18 +1283,13 @@
1921 que_thr_t* thr) /*!< in: query thread */
1922 {
1923 que_thr_t* next_thr;
1924- ulint cumul_resource;
1925 ulint loop_count;
1926
1927 ut_ad(thr->state == QUE_THR_RUNNING);
1928 ut_a(thr_get_trx(thr)->error_state == DB_SUCCESS);
1929 ut_ad(!mutex_own(&kernel_mutex));
1930
1931- /* cumul_resource counts how much resources the OS thread (NOT the
1932- query thread) has spent in this function */
1933-
1934 loop_count = QUE_MAX_LOOPS_WITHOUT_CHECK;
1935- cumul_resource = 0;
1936 loop:
1937 /* Check that there is enough space in the log to accommodate
1938 possible log entries by this query step; if the operation can touch
1939
1940=== modified file 'plugin/innobase/row/row0merge.c'
1941--- plugin/innobase/row/row0merge.c 2010-11-17 05:58:04 +0000
1942+++ plugin/innobase/row/row0merge.c 2010-12-07 14:26:13 +0000
1943@@ -2464,7 +2464,7 @@
1944 goto err_exit;
1945 }
1946
1947- err = dict_load_foreigns(old_name, TRUE);
1948+ err = dict_load_foreigns(old_name, FALSE, TRUE);
1949
1950 if (err != DB_SUCCESS) {
1951 err_exit:
1952
1953=== modified file 'plugin/innobase/row/row0mysql.c'
1954--- plugin/innobase/row/row0mysql.c 2010-12-04 00:39:53 +0000
1955+++ plugin/innobase/row/row0mysql.c 2010-12-07 14:26:13 +0000
1956@@ -618,6 +618,13 @@
1957 "InnoDB: " REFMAN "forcing-recovery.html"
1958 " for help.\n", stderr);
1959 break;
1960+ case DB_FOREIGN_EXCEED_MAX_CASCADE:
1961+ fprintf(stderr, "InnoDB: Cannot delete/update rows with"
1962+ " cascading foreign key constraints that exceed max"
1963+ " depth of %lu\n"
1964+ "Please drop excessive foreign constraints"
1965+ " and try again\n", (ulong) DICT_FK_MAX_RECURSIVE_LOAD);
1966+ break;
1967 default:
1968 fprintf(stderr, "InnoDB: unknown error code %lu\n",
1969 (ulong) err);
1970@@ -1424,11 +1431,21 @@
1971 run_again:
1972 thr->run_node = node;
1973 thr->prev_node = node;
1974+ thr->fk_cascade_depth = 0;
1975
1976 row_upd_step(thr);
1977
1978+ /* The recursive call for cascading update/delete happens
1979+ in above row_upd_step(), reset the counter once we come
1980+ out of the recursive call, so it does not accumulate for
1981+ different row deletes */
1982+ thr->fk_cascade_depth = 0;
1983+
1984 err = trx->error_state;
1985
1986+ /* Reset fk_cascade_depth back to 0 */
1987+ thr->fk_cascade_depth = 0;
1988+
1989 if (err != DB_SUCCESS) {
1990 que_thr_stop_for_mysql(thr);
1991
1992@@ -1465,7 +1482,12 @@
1993 srv_n_rows_updated++;
1994 }
1995
1996- row_update_statistics_if_needed(prebuilt->table);
1997+ /* We update table statistics only if it is a DELETE or UPDATE
1998+ that changes indexed columns, UPDATEs that change only non-indexed
1999+ columns would not affect statistics. */
2000+ if (node->is_delete || !(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
2001+ row_update_statistics_if_needed(prebuilt->table);
2002+ }
2003
2004 trx->op_info = "";
2005
2006@@ -1619,12 +1641,27 @@
2007 trx_t* trx;
2008
2009 trx = thr_get_trx(thr);
2010+
2011+ /* Increment fk_cascade_depth to record the recursive call depth on
2012+ a single update/delete that affects multiple tables chained
2013+ together with foreign key relations. */
2014+ thr->fk_cascade_depth++;
2015+
2016+ if (thr->fk_cascade_depth > FK_MAX_CASCADE_DEL) {
2017+ return (DB_FOREIGN_EXCEED_MAX_CASCADE);
2018+ }
2019 run_again:
2020 thr->run_node = node;
2021 thr->prev_node = node;
2022
2023 row_upd_step(thr);
2024
2025+ /* The recursive call for cascading update/delete happens
2026+ in above row_upd_step(), reset the counter once we come
2027+ out of the recursive call, so it does not accumulate for
2028+ different row deletes */
2029+ thr->fk_cascade_depth = 0;
2030+
2031 err = trx->error_state;
2032
2033 /* Note that the cascade node is a subnode of another InnoDB
2034@@ -2087,7 +2124,7 @@
2035 name, reject_fks);
2036 if (err == DB_SUCCESS) {
2037 /* Check that also referencing constraints are ok */
2038- err = dict_load_foreigns(name, TRUE);
2039+ err = dict_load_foreigns(name, FALSE, TRUE);
2040 }
2041
2042 if (err != DB_SUCCESS) {
2043@@ -2780,6 +2817,15 @@
2044
2045 trx->table_id = table->id;
2046
2047+ /* Lock all index trees for this table, as we will
2048+ truncate the table/index and possibly change their metadata.
2049+ All DML/DDL are blocked by table level lock, with
2050+ a few exceptions such as queries into information schema
2051+ about the table, MySQL could try to access index stats
2052+ for this kind of query, we need to use index locks to
2053+ sync up */
2054+ dict_table_x_lock_indexes(table);
2055+
2056 if (table->space && !table->dir_path_of_temp_table) {
2057 /* Discard and create the single-table tablespace. */
2058 ulint space = table->space;
2059@@ -2796,6 +2842,7 @@
2060 || fil_create_new_single_table_tablespace(
2061 space, table->name, FALSE, flags,
2062 FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) {
2063+ dict_table_x_unlock_indexes(table);
2064 ut_print_timestamp(stderr);
2065 fprintf(stderr,
2066 " InnoDB: TRUNCATE TABLE %s failed to"
2067@@ -2899,6 +2946,10 @@
2068
2069 mem_heap_free(heap);
2070
2071+ /* Done with index truncation, release index tree locks,
2072+ subsequent work relates to table level metadata change */
2073+ dict_table_x_unlock_indexes(table);
2074+
2075 dict_hdr_get_new_id(&new_id, NULL, NULL);
2076
2077 info = pars_info_create();
2078@@ -3950,7 +4001,7 @@
2079 an ALTER, not in a RENAME. */
2080
2081 err = dict_load_foreigns(
2082- new_name, !old_is_tmp || trx->check_foreigns);
2083+ new_name, FALSE, !old_is_tmp || trx->check_foreigns);
2084
2085 if (err != DB_SUCCESS) {
2086 ut_print_timestamp(stderr);
2087
2088=== modified file 'plugin/innobase/row/row0purge.c'
2089--- plugin/innobase/row/row0purge.c 2010-11-17 05:41:53 +0000
2090+++ plugin/innobase/row/row0purge.c 2010-12-07 14:26:13 +0000
2091@@ -796,7 +796,9 @@
2092 que_thr_t* thr) /*!< in: query thread */
2093 {
2094 purge_node_t* node;
2095+#ifdef UNIV_DEBUG
2096 ulint err;
2097+#endif /* UNIV_DEBUG */
2098
2099 ut_ad(thr);
2100
2101@@ -804,9 +806,14 @@
2102
2103 ut_ad(que_node_get_type(node) == QUE_NODE_PURGE);
2104
2105- err = row_purge(node, thr);
2106+#ifdef UNIV_DEBUG
2107+ err =
2108+#endif /* UNIV_DEBUG */
2109+ row_purge(node, thr);
2110
2111- ut_ad(err == DB_SUCCESS);
2112+#ifdef UNIV_DEBUG
2113+ ut_a(err == DB_SUCCESS);
2114+#endif /* UNIV_DEBUG */
2115
2116 return(thr);
2117 }
2118
2119=== modified file 'plugin/innobase/row/row0sel.c'
2120--- plugin/innobase/row/row0sel.c 2010-11-17 06:03:24 +0000
2121+++ plugin/innobase/row/row0sel.c 2010-12-07 14:26:13 +0000
2122@@ -2692,19 +2692,12 @@
2123 ut_ad(prebuilt->mysql_template);
2124 ut_ad(prebuilt->default_rec);
2125 ut_ad(rec_offs_validate(rec, NULL, offsets));
2126- ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
2127
2128 if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) {
2129 mem_heap_free(prebuilt->blob_heap);
2130 prebuilt->blob_heap = NULL;
2131 }
2132
2133- /* init null bytes with default values as they might be
2134- left uninitialized in some cases and these uninited bytes
2135- might be copied into mysql record buffer that leads to
2136- valgrind warnings */
2137- memcpy(mysql_rec, prebuilt->default_rec, prebuilt->null_bitmap_len);
2138-
2139 for (i = 0; i < prebuilt->n_template ; i++) {
2140
2141 templ = prebuilt->mysql_template + i;
2142@@ -3377,6 +3370,7 @@
2143 mem_heap_t* heap = NULL;
2144 ulint offsets_[REC_OFFS_NORMAL_SIZE];
2145 ulint* offsets = offsets_;
2146+ ibool table_lock_waited = FALSE;
2147
2148 rec_offs_init(offsets_);
2149
2150@@ -3607,6 +3601,7 @@
2151 row_sel_try_search_shortcut_for_mysql().
2152 The latch will not be released until
2153 mtr_commit(&mtr). */
2154+ ut_ad(!rec_get_deleted_flag(rec, comp));
2155
2156 if (!row_sel_store_mysql_rec(buf, prebuilt,
2157 rec, offsets)) {
2158@@ -3722,6 +3717,44 @@
2159
2160 clust_index = dict_table_get_first_index(index->table);
2161
2162+ /* Do some start-of-statement preparations */
2163+
2164+ if (!prebuilt->sql_stat_start) {
2165+ /* No need to set an intention lock or assign a read view */
2166+
2167+ if (trx->read_view == NULL
2168+ && prebuilt->select_lock_type == LOCK_NONE) {
2169+
2170+ fputs("InnoDB: Error: MySQL is trying to"
2171+ " perform a consistent read\n"
2172+ "InnoDB: but the read view is not assigned!\n",
2173+ stderr);
2174+ trx_print(stderr, trx, 600);
2175+ fputc('\n', stderr);
2176+ ut_error;
2177+ }
2178+ } else if (prebuilt->select_lock_type == LOCK_NONE) {
2179+ /* This is a consistent read */
2180+ /* Assign a read view for the query */
2181+
2182+ trx_assign_read_view(trx);
2183+ prebuilt->sql_stat_start = FALSE;
2184+ } else {
2185+wait_table_again:
2186+ err = lock_table(0, index->table,
2187+ prebuilt->select_lock_type == LOCK_S
2188+ ? LOCK_IS : LOCK_IX, thr);
2189+
2190+ if (err != DB_SUCCESS) {
2191+
2192+ table_lock_waited = TRUE;
2193+ goto lock_table_wait;
2194+ }
2195+ prebuilt->sql_stat_start = FALSE;
2196+ }
2197+
2198+ /* Open or restore index cursor position */
2199+
2200 if (UNIV_LIKELY(direction != 0)) {
2201 ibool need_to_process = sel_restore_position_for_mysql(
2202 &same_user_rec, BTR_SEARCH_LEAF,
2203@@ -3797,42 +3830,6 @@
2204 }
2205 }
2206
2207- if (!prebuilt->sql_stat_start) {
2208- /* No need to set an intention lock or assign a read view */
2209-
2210- if (trx->read_view == NULL
2211- && prebuilt->select_lock_type == LOCK_NONE) {
2212-
2213- fputs("InnoDB: Error: MySQL is trying to"
2214- " perform a consistent read\n"
2215- "InnoDB: but the read view is not assigned!\n",
2216- stderr);
2217- trx_print(stderr, trx, 600);
2218- fputc('\n', stderr);
2219- ut_a(0);
2220- }
2221- } else if (prebuilt->select_lock_type == LOCK_NONE) {
2222- /* This is a consistent read */
2223- /* Assign a read view for the query */
2224-
2225- trx_assign_read_view(trx);
2226- prebuilt->sql_stat_start = FALSE;
2227- } else {
2228- ulint lock_mode;
2229- if (prebuilt->select_lock_type == LOCK_S) {
2230- lock_mode = LOCK_IS;
2231- } else {
2232- lock_mode = LOCK_IX;
2233- }
2234- err = lock_table(0, index->table, lock_mode, thr);
2235-
2236- if (err != DB_SUCCESS) {
2237-
2238- goto lock_wait_or_error;
2239- }
2240- prebuilt->sql_stat_start = FALSE;
2241- }
2242-
2243 rec_loop:
2244 /*-------------------------------------------------------------*/
2245 /* PHASE 4: Look for matching records in a loop */
2246@@ -4248,7 +4245,7 @@
2247
2248 rec = old_vers;
2249 }
2250- } else if (!lock_sec_rec_cons_read_sees(rec, trx->read_view)) {
2251+ } else {
2252 /* We are looking into a non-clustered index,
2253 and to get the right version of the record we
2254 have to look also into the clustered index: this
2255@@ -4256,7 +4253,11 @@
2256 information via the clustered index record. */
2257
2258 ut_ad(index != clust_index);
2259- goto requires_clust_rec;
2260+ ut_ad(!dict_index_is_clust(index));
2261+ if (!lock_sec_rec_cons_read_sees(
2262+ rec, trx->read_view)) {
2263+ goto requires_clust_rec;
2264+ }
2265 }
2266 }
2267
2268@@ -4379,8 +4380,13 @@
2269 ULINT_UNDEFINED, &heap);
2270 result_rec = rec;
2271 }
2272+
2273+ /* result_rec can legitimately be delete-marked
2274+ now that it has been established that it points to a
2275+ clustered index record that exists in the read view. */
2276 } else {
2277 result_rec = rec;
2278+ ut_ad(!rec_get_deleted_flag(rec, comp));
2279 }
2280
2281 /* We found a qualifying record 'result_rec'. At this point,
2282@@ -4557,6 +4563,7 @@
2283
2284 btr_pcur_store_position(pcur, &mtr);
2285
2286+lock_table_wait:
2287 mtr_commit(&mtr);
2288 mtr_has_extra_clust_latch = FALSE;
2289
2290@@ -4574,6 +4581,14 @@
2291 thr->lock_state = QUE_THR_LOCK_NOLOCK;
2292 mtr_start(&mtr);
2293
2294+ /* Table lock waited, go try to obtain table lock
2295+ again */
2296+ if (table_lock_waited) {
2297+ table_lock_waited = FALSE;
2298+
2299+ goto wait_table_again;
2300+ }
2301+
2302 sel_restore_position_for_mysql(&same_user_rec,
2303 BTR_SEARCH_LEAF, pcur,
2304 moves_up, &mtr);
2305
2306=== modified file 'plugin/innobase/row/row0umod.c'
2307--- plugin/innobase/row/row0umod.c 2010-11-17 05:41:53 +0000
2308+++ plugin/innobase/row/row0umod.c 2010-12-07 14:26:13 +0000
2309@@ -114,12 +114,17 @@
2310 btr_pcur_t* pcur;
2311 btr_cur_t* btr_cur;
2312 ulint err;
2313+#ifdef UNIV_DEBUG
2314 ibool success;
2315+#endif /* UNIV_DEBUG */
2316
2317 pcur = &(node->pcur);
2318 btr_cur = btr_pcur_get_btr_cur(pcur);
2319
2320- success = btr_pcur_restore_position(mode, pcur, mtr);
2321+#ifdef UNIV_DEBUG
2322+ success =
2323+#endif /* UNIV_DEBUG */
2324+ btr_pcur_restore_position(mode, pcur, mtr);
2325
2326 ut_ad(success);
2327
2328
2329=== modified file 'plugin/innobase/row/row0upd.c'
2330--- plugin/innobase/row/row0upd.c 2010-11-17 05:58:24 +0000
2331+++ plugin/innobase/row/row0upd.c 2010-12-07 14:26:13 +0000
2332@@ -1636,6 +1636,7 @@
2333 dict_table_t* table;
2334 dtuple_t* entry;
2335 ulint err;
2336+ ibool change_ownership = FALSE;
2337
2338 ut_ad(node);
2339 ut_ad(dict_index_is_clust(index));
2340@@ -1668,9 +1669,9 @@
2341 index = dict_table_get_first_index(table);
2342 offsets = rec_get_offsets(rec, index, offsets_,
2343 ULINT_UNDEFINED, &heap);
2344- btr_cur_mark_extern_inherited_fields(
2345- btr_cur_get_page_zip(btr_cur),
2346- rec, index, offsets, node->update, mtr);
2347+ change_ownership = btr_cur_mark_extern_inherited_fields(
2348+ btr_cur_get_page_zip(btr_cur), rec, index, offsets,
2349+ node->update, mtr);
2350 if (referenced) {
2351 /* NOTE that the following call loses
2352 the position of pcur ! */
2353@@ -1704,10 +1705,11 @@
2354
2355 row_upd_index_entry_sys_field(entry, index, DATA_TRX_ID, trx->id);
2356
2357- if (node->upd_ext) {
2358+ if (change_ownership) {
2359 /* If we return from a lock wait, for example, we may have
2360 extern fields marked as not-owned in entry (marked in the
2361- if-branch above). We must unmark them. */
2362+ if-branch above). We must unmark them, take the ownership
2363+ back. */
2364
2365 btr_cur_unmark_dtuple_extern_fields(entry);
2366
2367
2368=== modified file 'plugin/innobase/row/row0vers.c'
2369--- plugin/innobase/row/row0vers.c 2010-11-17 05:41:53 +0000
2370+++ plugin/innobase/row/row0vers.c 2010-12-07 14:26:13 +0000
2371@@ -71,7 +71,9 @@
2372 warning */
2373 trx_t* trx;
2374 ulint rec_del;
2375+#ifdef UNIV_DEBUG
2376 ulint err;
2377+#endif /* UNIV_DEBUG */
2378 mtr_t mtr;
2379 ulint comp;
2380
2381@@ -169,9 +171,12 @@
2382
2383 heap2 = heap;
2384 heap = mem_heap_create(1024);
2385- err = trx_undo_prev_version_build(clust_rec, &mtr, version,
2386- clust_index, clust_offsets,
2387- heap, &prev_version);
2388+#ifdef UNIV_DEBUG
2389+ err =
2390+#endif /* UNIV_DEBUG */
2391+ trx_undo_prev_version_build(clust_rec, &mtr, version,
2392+ clust_index, clust_offsets,
2393+ heap, &prev_version);
2394 mem_heap_free(heap2); /* free version and clust_offsets */
2395
2396 if (prev_version == NULL) {
2397
2398=== modified file 'plugin/innobase/srv/srv0srv.c'
2399--- plugin/innobase/srv/srv0srv.c 2010-11-19 05:36:07 +0000
2400+++ plugin/innobase/srv/srv0srv.c 2010-12-07 14:26:13 +0000
2401@@ -463,6 +463,7 @@
2402 UNIV_INTERN ib_int64_t srv_n_lock_wait_time = 0;
2403 UNIV_INTERN ulint srv_n_lock_max_wait_time = 0;
2404
2405+UNIV_INTERN ulint srv_truncated_status_writes = 0;
2406
2407 /*
2408 Set the following to 0 if you want InnoDB to write messages on
2409@@ -1619,6 +1620,18 @@
2410 row_mysql_unfreeze_data_dictionary(trx);
2411 break;
2412 case RW_X_LATCH:
2413+ /* There should never be a lock wait when the
2414+ dictionary latch is reserved in X mode. Dictionary
2415+ transactions should only acquire locks on dictionary
2416+ tables, not other tables. All access to dictionary
2417+ tables should be covered by dictionary
2418+ transactions. */
2419+ ut_print_timestamp(stderr);
2420+ fputs(" InnoDB: Error: dict X latch held in "
2421+ "srv_suspend_mysql_thread\n", stderr);
2422+ /* This should never occur. This incorrect handling
2423+ was added in the early development of
2424+ ha_innobase::add_index() in InnoDB Plugin 1.0. */
2425 /* Release fast index creation latch */
2426 row_mysql_unlock_data_dictionary(trx);
2427 break;
2428@@ -1638,6 +1651,9 @@
2429 row_mysql_freeze_data_dictionary(trx);
2430 break;
2431 case RW_X_LATCH:
2432+ /* This should never occur. This incorrect handling
2433+ was added in the early development of
2434+ ha_innobase::add_index() in InnoDB Plugin 1.0. */
2435 row_mysql_lock_data_dictionary(trx);
2436 break;
2437 }
2438@@ -2042,6 +2058,7 @@
2439 export_vars.innodb_rows_inserted = srv_n_rows_inserted;
2440 export_vars.innodb_rows_updated = srv_n_rows_updated;
2441 export_vars.innodb_rows_deleted = srv_n_rows_deleted;
2442+ export_vars.innodb_truncated_status_writes = srv_truncated_status_writes;
2443
2444 mutex_exit(&srv_innodb_monitor_mutex);
2445 }
2446@@ -2647,7 +2664,9 @@
2447 when there is database activity */
2448
2449 srv_last_log_flush_time = time(NULL);
2450- next_itr_time = ut_time_ms();
2451+
2452+ /* Sleep for 1 second on entrying the for loop below the first time. */
2453+ next_itr_time = ut_time_ms() + 1000;
2454
2455 for (i = 0; i < 10; i++) {
2456 ulint cur_time = ut_time_ms();
2457
2458=== modified file 'plugin/innobase/srv/srv0start.c'
2459--- plugin/innobase/srv/srv0start.c 2010-11-17 06:09:19 +0000
2460+++ plugin/innobase/srv/srv0start.c 2010-12-07 14:26:13 +0000
2461@@ -1327,8 +1327,27 @@
2462 fil_init(srv_file_per_table ? 50000 : 5000,
2463 srv_max_n_open_files);
2464
2465+ /* Print time to initialize the buffer pool */
2466+ ut_print_timestamp(stderr);
2467+ fprintf(stderr,
2468+ " InnoDB: Initializing buffer pool, size =");
2469+
2470+ if (srv_buf_pool_size >= 1024 * 1024 * 1024) {
2471+ fprintf(stderr,
2472+ " %.1fG\n",
2473+ ((double) srv_buf_pool_size) / (1024 * 1024 * 1024));
2474+ } else {
2475+ fprintf(stderr,
2476+ " %.1fM\n",
2477+ ((double) srv_buf_pool_size) / (1024 * 1024));
2478+ }
2479+
2480 err = buf_pool_init(srv_buf_pool_size, srv_buf_pool_instances);
2481
2482+ ut_print_timestamp(stderr);
2483+ fprintf(stderr,
2484+ " InnoDB: Completed initialization of buffer pool\n");
2485+
2486 if (err != DB_SUCCESS) {
2487 fprintf(stderr,
2488 "InnoDB: Fatal error: cannot allocate the memory"
2489@@ -1845,7 +1864,7 @@
2490 if (srv_print_verbose_log) {
2491 ut_print_timestamp(stderr);
2492 fprintf(stderr,
2493- " InnoDB %s started; "
2494+ " InnoDB %s started; "
2495 "log sequence number %"PRIu64"\n",
2496 INNODB_VERSION_STR, srv_start_lsn);
2497 }
2498
2499=== modified file 'plugin/innobase/tests/r/index_merge_innodb.result'
2500--- plugin/innobase/tests/r/index_merge_innodb.result 2010-09-12 14:34:27 +0000
2501+++ plugin/innobase/tests/r/index_merge_innodb.result 2010-12-07 14:26:13 +0000
2502@@ -178,6 +178,61 @@
2503 38 38 38
2504 39 39 39
2505 drop table t1;
2506+#
2507+# Bug#56423: Different count with SELECT and CREATE SELECT queries
2508+#
2509+CREATE TABLE t1 (
2510+a INT,
2511+b INT,
2512+c INT,
2513+d INT,
2514+PRIMARY KEY (a),
2515+KEY (c),
2516+KEY bd (b,d)
2517+);
2518+INSERT INTO t1 VALUES
2519+(1, 0, 1, 0),
2520+(2, 1, 1, 1),
2521+(3, 1, 1, 1),
2522+(4, 0, 1, 1);
2523+EXPLAIN
2524+SELECT a
2525+FROM t1
2526+WHERE c = 1 AND b = 1 AND d = 1;
2527+id select_type table type possible_keys key key_len ref rows Extra
2528+1 SIMPLE t1 ref c,bd bd 10 const,const 2 Using where
2529+CREATE TABLE t2 ( a INT )
2530+SELECT a
2531+FROM t1
2532+WHERE c = 1 AND b = 1 AND d = 1;
2533+SELECT * FROM t2;
2534+a
2535+2
2536+3
2537+DROP TABLE t1, t2;
2538+CREATE TABLE t1( a INT, b INT, KEY(a), KEY(b) );
2539+INSERT INTO t1 VALUES (1, 2), (1, 2), (1, 2), (1, 2);
2540+SELECT * FROM t1 FORCE INDEX(a, b) WHERE a = 1 AND b = 2;
2541+a b
2542+1 2
2543+1 2
2544+1 2
2545+1 2
2546+DROP TABLE t1;
2547+# Code coverage of fix.
2548+CREATE TABLE t1 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT);
2549+INSERT INTO t1 (b) VALUES (1);
2550+UPDATE t1 SET b = 2 WHERE a = 1;
2551+SELECT * FROM t1;
2552+a b
2553+1 2
2554+CREATE TABLE t2 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b VARCHAR(1) );
2555+INSERT INTO t2 (b) VALUES ('a');
2556+UPDATE t2 SET b = 'b' WHERE a = 1;
2557+SELECT * FROM t2;
2558+a b
2559+1 b
2560+DROP TABLE t1, t2;
2561 #---------------- 2-sweeps read Index merge test 2 -------------------------------
2562 SET SESSION STORAGE_ENGINE = InnoDB;
2563 drop table if exists t1;
2564
2565=== added file 'plugin/innobase/tests/r/innodb_bug56716.result'
2566--- plugin/innobase/tests/r/innodb_bug56716.result 1970-01-01 00:00:00 +0000
2567+++ plugin/innobase/tests/r/innodb_bug56716.result 2010-12-07 14:26:13 +0000
2568@@ -0,0 +1,4 @@
2569+CREATE TABLE bug56716 (a INT PRIMARY KEY,b INT,c INT,INDEX(b)) ENGINE=InnoDB;
2570+SELECT * FROM bug56716 WHERE b<=42 ORDER BY b DESC FOR UPDATE;
2571+a b c
2572+DROP TABLE bug56716;
2573
2574=== added file 'plugin/innobase/tests/r/innodb_bug57255.result'
2575--- plugin/innobase/tests/r/innodb_bug57255.result 1970-01-01 00:00:00 +0000
2576+++ plugin/innobase/tests/r/innodb_bug57255.result 2010-12-07 14:26:13 +0000
2577@@ -0,0 +1,10 @@
2578+create table A(id int not null primary key) engine=innodb;
2579+create table B(id int not null auto_increment primary key, f1 int not null, foreign key(f1) references A(id) on delete cascade) engine=innodb;
2580+create table C(id int not null auto_increment primary key, f1 int not null, foreign key(f1) references B(id) on delete cascade) engine=innodb;
2581+insert into A values(1), (2);
2582+DELETE FROM A where id = 1;
2583+DELETE FROM C where f1 = 2;
2584+DELETE FROM A where id = 1;
2585+DROP TABLE C;
2586+DROP TABLE B;
2587+DROP TABLE A;
2588
2589=== modified file 'plugin/innobase/tests/r/innodb_mysql.result'
2590--- plugin/innobase/tests/r/innodb_mysql.result 2010-12-04 09:02:32 +0000
2591+++ plugin/innobase/tests/r/innodb_mysql.result 2010-12-07 14:26:13 +0000
2592@@ -1352,3 +1352,35 @@
2593 DROP TABLE t1;
2594 SET GLOBAL innodb_lock_wait_timeout=@orig_lock_wait_timeout ;
2595 End of 5.1 tests
2596+#
2597+# Test for bug #39932 "create table fails if column for FK is in different
2598+# case than in corr index".
2599+#
2600+drop tables if exists t1, t2;
2601+create table t1 (pk int primary key) engine=InnoDB;
2602+# Even although the below statement uses uppercased field names in
2603+# foreign key definition it still should be able to find explicitly
2604+# created supporting index. So it should succeed and should not
2605+# create any additional supporting indexes.
2606+create table t2 (fk int, key x (fk),
2607+constraint x foreign key (FK) references t1 (PK)) engine=InnoDB;
2608+show create table t2;
2609+Table Create Table
2610+t2 CREATE TABLE `t2` (
2611+ `fk` INT DEFAULT NULL,
2612+ KEY `x` (`fk`),
2613+ CONSTRAINT `x` FOREIGN KEY (`FK`) REFERENCES `t1` (`PK`)
2614+) ENGINE=InnoDB COLLATE = utf8_general_ci
2615+drop table t2, t1;
2616+#
2617+# Bug#55826: create table .. select crashes with when KILL_BAD_DATA
2618+# is returned
2619+#
2620+CREATE TABLE t1(a INT) ENGINE=innodb;
2621+INSERT INTO t1 VALUES (0);
2622+CREATE TABLE t2
2623+SELECT LEAST((SELECT '' FROM t1),NOW()) FROM `t1`;
2624+ERROR 22007: Incorrect datetime value: '' for column 'NOW()' at row 1
2625+DROP TABLE IF EXISTS t1,t2;
2626+Warnings:
2627+Note 1051 Unknown table 't2'
2628
2629=== modified file 'plugin/innobase/tests/t/innodb-autoinc.test'
2630--- plugin/innobase/tests/t/innodb-autoinc.test 2010-11-17 01:27:10 +0000
2631+++ plugin/innobase/tests/t/innodb-autoinc.test 2010-12-07 14:26:13 +0000
2632@@ -76,6 +76,18 @@
2633 SHOW CREATE TABLE t1;
2634 DROP TABLE t1;
2635
2636+###
2637+## 55277: Failing assertion: auto_inc > 0
2638+##
2639+#DROP TABLE IF EXISTS t1;
2640+#CREATE TABLE t1(c1 BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
2641+#INSERT INTO t1 VALUES (NULL);
2642+#INSERT INTO t1 VALUES (18446744073709551615);
2643+## Restart the server
2644+#-- source include/restart_mysqld.inc
2645+#SHOW CREATE TABLE t1;
2646+#DROP TABLE t1;
2647+
2648
2649 #
2650 # restore environment to the state it was before this test execution
2651
2652=== modified file 'plugin/innobase/tests/t/innodb_bug53756.test'
2653--- plugin/innobase/tests/t/innodb_bug53756.test 2010-11-11 02:30:41 +0000
2654+++ plugin/innobase/tests/t/innodb_bug53756.test 2010-12-07 14:26:13 +0000
2655@@ -34,8 +34,8 @@
2656 --echo
2657 --echo # Select a less restrictive isolation level.
2658 # Don't use user variables. They won't survive server crash.
2659---let $global_isolation= `SELECT @@global.tx_isolation`;
2660---let $session_isolation= `SELECT @@session.tx_isolation`;
2661+--let $global_isolation= `SELECT @@global.tx_isolation`
2662+--let $session_isolation= `SELECT @@session.tx_isolation`
2663 SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
2664 SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
2665 COMMIT;
2666
2667=== added file 'plugin/innobase/tests/t/innodb_bug56716.test'
2668--- plugin/innobase/tests/t/innodb_bug56716.test 1970-01-01 00:00:00 +0000
2669+++ plugin/innobase/tests/t/innodb_bug56716.test 2010-12-07 14:26:13 +0000
2670@@ -0,0 +1,10 @@
2671+#
2672+# Bug #56716 InnoDB locks a record gap without locking the table
2673+#
2674+-- source include/have_innodb.inc
2675+
2676+CREATE TABLE bug56716 (a INT PRIMARY KEY,b INT,c INT,INDEX(b)) ENGINE=InnoDB;
2677+
2678+SELECT * FROM bug56716 WHERE b<=42 ORDER BY b DESC FOR UPDATE;
2679+
2680+DROP TABLE bug56716;
2681
2682=== added file 'plugin/innobase/tests/t/innodb_bug57255.test'
2683--- plugin/innobase/tests/t/innodb_bug57255.test 1970-01-01 00:00:00 +0000
2684+++ plugin/innobase/tests/t/innodb_bug57255.test 2010-12-07 14:26:13 +0000
2685@@ -0,0 +1,38 @@
2686+# Test Bug #57255. Cascade deletes that affect different rows should not
2687+# result in DB_FOREIGN_EXCEED_MAX_CASCADE error
2688+
2689+--source include/have_innodb.inc
2690+
2691+create table A(id int not null primary key) engine=innodb;
2692+
2693+create table B(id int not null auto_increment primary key, f1 int not null, foreign key(f1) references A(id) on delete cascade) engine=innodb;
2694+
2695+create table C(id int not null auto_increment primary key, f1 int not null, foreign key(f1) references B(id) on delete cascade) engine=innodb;
2696+
2697+insert into A values(1), (2);
2698+
2699+--disable_query_log
2700+begin;
2701+let $i=257;
2702+while ($i)
2703+{
2704+insert into B(f1) values(1);
2705+dec $i;
2706+}
2707+let $i=486;
2708+while ($i)
2709+{
2710+insert into C(f1) values(2);
2711+dec $i;
2712+}
2713+commit;
2714+--enable_query_log
2715+
2716+# Following Deletes should not report error
2717+DELETE FROM A where id = 1;
2718+DELETE FROM C where f1 = 2;
2719+DELETE FROM A where id = 1;
2720+
2721+DROP TABLE C;
2722+DROP TABLE B;
2723+DROP TABLE A;
2724
2725=== modified file 'plugin/innobase/tests/t/innodb_mysql.test'
2726--- plugin/innobase/tests/t/innodb_mysql.test 2010-12-04 09:02:32 +0000
2727+++ plugin/innobase/tests/t/innodb_mysql.test 2010-12-07 14:26:13 +0000
2728@@ -12,3 +12,31 @@
2729 let $test_foreign_keys= 1;
2730 set global innodb_support_xa=default;
2731 --source include/mix1.inc
2732+
2733+--echo #
2734+--echo # Test for bug #39932 "create table fails if column for FK is in different
2735+--echo # case than in corr index".
2736+--echo #
2737+--disable_warnings
2738+drop tables if exists t1, t2;
2739+--enable_warnings
2740+create table t1 (pk int primary key) engine=InnoDB;
2741+--echo # Even although the below statement uses uppercased field names in
2742+--echo # foreign key definition it still should be able to find explicitly
2743+--echo # created supporting index. So it should succeed and should not
2744+--echo # create any additional supporting indexes.
2745+create table t2 (fk int, key x (fk),
2746+ constraint x foreign key (FK) references t1 (PK)) engine=InnoDB;
2747+show create table t2;
2748+drop table t2, t1;
2749+--echo #
2750+--echo # Bug#55826: create table .. select crashes with when KILL_BAD_DATA
2751+--echo # is returned
2752+--echo #
2753+
2754+CREATE TABLE t1(a INT) ENGINE=innodb;
2755+INSERT INTO t1 VALUES (0);
2756+--error ER_TRUNCATED_WRONG_VALUE
2757+CREATE TABLE t2
2758+ SELECT LEAST((SELECT '' FROM t1),NOW()) FROM `t1`;
2759+DROP TABLE IF EXISTS t1,t2;
2760
2761=== modified file 'plugin/innobase/trx/trx0purge.c'
2762--- plugin/innobase/trx/trx0purge.c 2010-12-02 07:43:37 +0000
2763+++ plugin/innobase/trx/trx0purge.c 2010-12-07 14:26:13 +0000
2764@@ -313,9 +313,10 @@
2765 trx_undo_t* undo;
2766 trx_rseg_t* rseg;
2767 trx_rsegf_t* rseg_header;
2768+#ifdef UNIV_DEBUG
2769 trx_usegf_t* seg_header;
2770+#endif /* UNIV_DEBUG */
2771 trx_ulogf_t* undo_header;
2772- trx_upagef_t* page_header;
2773 ulint hist_size;
2774
2775 undo = trx->update_undo;
2776@@ -330,8 +331,9 @@
2777 rseg->page_no, mtr);
2778
2779 undo_header = undo_page + undo->hdr_offset;
2780+#ifdef UNIV_DEBUG
2781 seg_header = undo_page + TRX_UNDO_SEG_HDR;
2782- page_header = undo_page + TRX_UNDO_PAGE_HDR;
2783+#endif /* UNIV_DEBUG */
2784
2785 if (undo->state != TRX_UNDO_CACHED) {
2786 /* The undo log segment will not be reused */
2787@@ -669,7 +671,6 @@
2788 {
2789 page_t* undo_page;
2790 trx_ulogf_t* log_hdr;
2791- trx_usegf_t* seg_hdr;
2792 fil_addr_t prev_log_addr;
2793 trx_id_t trx_no;
2794 ibool del_marks;
2795@@ -690,7 +691,6 @@
2796 undo_page = trx_undo_page_get_s_latched(rseg->space, rseg->zip_size,
2797 rseg->last_page_no, &mtr);
2798 log_hdr = undo_page + rseg->last_offset;
2799- seg_hdr = undo_page + TRX_UNDO_SEG_HDR;
2800
2801 /* Increase the purge page count by one for every handled log */
2802
2803@@ -1079,12 +1079,8 @@
2804 /*==================*/
2805 trx_undo_inf_t* cell) /*!< in: storage cell */
2806 {
2807- trx_undo_arr_t* arr;
2808-
2809 mutex_enter(&(purge_sys->mutex));
2810
2811- arr = purge_sys->arr;
2812-
2813 trx_purge_arr_remove_info(cell);
2814
2815 mutex_exit(&(purge_sys->mutex));
2816
2817=== modified file 'plugin/innobase/trx/trx0roll.c'
2818--- plugin/innobase/trx/trx0roll.c 2010-12-02 07:43:37 +0000
2819+++ plugin/innobase/trx/trx0roll.c 2010-12-07 14:26:13 +0000
2820@@ -743,13 +743,8 @@
2821 undo_no_t undo_no)/*!< in: undo number */
2822 {
2823 trx_undo_inf_t* cell;
2824- ulint n_used;
2825- ulint n;
2826 ulint i;
2827
2828- n_used = arr->n_used;
2829- n = 0;
2830-
2831 for (i = 0;; i++) {
2832 cell = trx_undo_arr_get_nth_info(arr, i);
2833
2834
2835=== modified file 'plugin/innobase/trx/trx0sys.c'
2836--- plugin/innobase/trx/trx0sys.c 2010-12-02 07:43:37 +0000
2837+++ plugin/innobase/trx/trx0sys.c 2010-12-07 14:26:13 +0000
2838@@ -249,7 +249,9 @@
2839 {
2840 buf_block_t* block;
2841 buf_block_t* block2;
2842+#ifdef UNIV_SYNC_DEBUG
2843 buf_block_t* new_block;
2844+#endif /* UNIV_SYNC_DEBUG */
2845 byte* doublewrite;
2846 byte* fseg_header;
2847 ulint page_no;
2848@@ -352,8 +354,11 @@
2849 the page position in the tablespace, then the page
2850 has not been written to in doublewrite. */
2851
2852- new_block = buf_page_get(TRX_SYS_SPACE, 0, page_no,
2853- RW_X_LATCH, &mtr);
2854+#ifdef UNIV_SYNC_DEBUG
2855+ new_block =
2856+#endif /* UNIV_SYNC_DEBUG */
2857+ buf_page_get(TRX_SYS_SPACE, 0, page_no,
2858+ RW_X_LATCH, &mtr);
2859 buf_block_dbg_add_level(new_block,
2860 SYNC_NO_ORDER_CHECK);
2861
2862
2863=== modified file 'plugin/innobase/trx/trx0trx.c'
2864--- plugin/innobase/trx/trx0trx.c 2010-12-02 07:43:37 +0000
2865+++ plugin/innobase/trx/trx0trx.c 2010-12-07 14:26:13 +0000
2866@@ -1793,7 +1793,6 @@
2867 /*===================*/
2868 trx_t* trx) /*!< in: transaction */
2869 {
2870- page_t* update_hdr_page;
2871 trx_rseg_t* rseg;
2872 ib_uint64_t lsn = 0;
2873 mtr_t mtr;
2874@@ -1826,7 +1825,7 @@
2875 }
2876
2877 if (trx->update_undo) {
2878- update_hdr_page = trx_undo_set_state_at_prepare(
2879+ trx_undo_set_state_at_prepare(
2880 trx, trx->update_undo, &mtr);
2881 }
2882
2883
2884=== modified file 'plugin/innobase/trx/trx0undo.c'
2885--- plugin/innobase/trx/trx0undo.c 2010-11-17 05:43:11 +0000
2886+++ plugin/innobase/trx/trx0undo.c 2010-12-07 14:26:13 +0000
2887@@ -1072,14 +1072,11 @@
2888 ulint last_page_no;
2889 trx_undo_rec_t* rec;
2890 trx_undo_rec_t* trunc_here;
2891- trx_rseg_t* rseg;
2892 mtr_t mtr;
2893
2894 ut_ad(mutex_own(&(trx->undo_mutex)));
2895 ut_ad(mutex_own(&(trx->rseg->mutex)));
2896
2897- rseg = trx->rseg;
2898-
2899 for (;;) {
2900 mtr_start(&mtr);
2901
2902@@ -1873,7 +1870,6 @@
2903 mtr_t* mtr) /*!< in: mtr */
2904 {
2905 trx_usegf_t* seg_hdr;
2906- trx_upagef_t* page_hdr;
2907 trx_ulogf_t* undo_header;
2908 page_t* undo_page;
2909 ulint offset;
2910@@ -1891,7 +1887,6 @@
2911 undo->hdr_page_no, mtr);
2912
2913 seg_hdr = undo_page + TRX_UNDO_SEG_HDR;
2914- page_hdr = undo_page + TRX_UNDO_PAGE_HDR;
2915
2916 /*------------------------------*/
2917 undo->state = TRX_UNDO_PREPARED;
2918
2919=== removed file 'plugin/innobase/ut/ut0auxconf_atomic_pthread_t_gcc.c'
2920--- plugin/innobase/ut/ut0auxconf_atomic_pthread_t_gcc.c 2010-10-02 21:15:42 +0000
2921+++ plugin/innobase/ut/ut0auxconf_atomic_pthread_t_gcc.c 1970-01-01 00:00:00 +0000
2922@@ -1,43 +0,0 @@
2923-/*****************************************************************************
2924-
2925-Copyright (c) 2009, Innobase Oy. All Rights Reserved.
2926-
2927-This program is free software; you can redistribute it and/or modify it under
2928-the terms of the GNU General Public License as published by the Free Software
2929-Foundation; version 2 of the License.
2930-
2931-This program is distributed in the hope that it will be useful, but WITHOUT
2932-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
2933-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
2934-
2935-You should have received a copy of the GNU General Public License along with
2936-this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
2937-St, Fifth Floor, Boston, MA 02110-1301 USA
2938-
2939-*****************************************************************************/
2940-
2941-/*****************************************************************************
2942-If this program compiles, then pthread_t objects can be used as arguments
2943-to GCC atomic builtin functions.
2944-
2945-Created March 5, 2009 Vasil Dimov
2946-*****************************************************************************/
2947-
2948-#include <pthread.h>
2949-#include <string.h>
2950-
2951-int
2952-main(int argc, char** argv)
2953-{
2954- pthread_t x1;
2955- pthread_t x2;
2956- pthread_t x3;
2957-
2958- memset(&x1, 0x0, sizeof(x1));
2959- memset(&x2, 0x0, sizeof(x2));
2960- memset(&x3, 0x0, sizeof(x3));
2961-
2962- __sync_bool_compare_and_swap(&x1, x2, x3);
2963-
2964- return(0);
2965-}
2966
2967=== removed file 'plugin/innobase/ut/ut0auxconf_atomic_pthread_t_solaris.c'
2968--- plugin/innobase/ut/ut0auxconf_atomic_pthread_t_solaris.c 2010-10-12 05:41:31 +0000
2969+++ plugin/innobase/ut/ut0auxconf_atomic_pthread_t_solaris.c 1970-01-01 00:00:00 +0000
2970@@ -1,54 +0,0 @@
2971-/*****************************************************************************
2972-
2973-Copyright (c) 2009, Innobase Oy. All Rights Reserved.
2974-
2975-This program is free software; you can redistribute it and/or modify it under
2976-the terms of the GNU General Public License as published by the Free Software
2977-Foundation; version 2 of the License.
2978-
2979-This program is distributed in the hope that it will be useful, but WITHOUT
2980-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
2981-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
2982-
2983-You should have received a copy of the GNU General Public License along with
2984-this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
2985-St, Fifth Floor, Boston, MA 02110-1301 USA
2986-
2987-*****************************************************************************/
2988-
2989-/*****************************************************************************
2990-If this program compiles and returns 0, then pthread_t objects can be used as
2991-arguments to Solaris libc atomic functions.
2992-
2993-Created April 18, 2009 Vasil Dimov
2994-*****************************************************************************/
2995-
2996-#include <pthread.h>
2997-#include <string.h>
2998-
2999-int
3000-main(int argc, char** argv)
3001-{
3002- pthread_t x1;
3003- pthread_t x2;
3004- pthread_t x3;
3005-
3006- memset(&x1, 0x0, sizeof(x1));
3007- memset(&x2, 0x0, sizeof(x2));
3008- memset(&x3, 0x0, sizeof(x3));
3009-
3010- if (sizeof(pthread_t) == 4) {
3011-
3012- atomic_cas_32(&x1, x2, x3);
3013-
3014- } else if (sizeof(pthread_t) == 8) {
3015-
3016- atomic_cas_64(&x1, x2, x3);
3017-
3018- } else {
3019-
3020- return(1);
3021- }
3022-
3023- return(0);
3024-}
3025
3026=== removed file 'plugin/innobase/ut/ut0auxconf_have_gcc_atomics.c'
3027--- plugin/innobase/ut/ut0auxconf_have_gcc_atomics.c 2010-10-12 05:41:32 +0000
3028+++ plugin/innobase/ut/ut0auxconf_have_gcc_atomics.c 1970-01-01 00:00:00 +0000
3029@@ -1,61 +0,0 @@
3030-/*****************************************************************************
3031-
3032-Copyright (c) 2009, Innobase Oy. All Rights Reserved.
3033-
3034-This program is free software; you can redistribute it and/or modify it under
3035-the terms of the GNU General Public License as published by the Free Software
3036-Foundation; version 2 of the License.
3037-
3038-This program is distributed in the hope that it will be useful, but WITHOUT
3039-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
3040-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
3041-
3042-You should have received a copy of the GNU General Public License along with
3043-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
3044-Place, Suite 330, Boston, MA 02111-1307 USA
3045-
3046-*****************************************************************************/
3047-
3048-/*****************************************************************************
3049-If this program compiles and returns 0, then GCC atomic funcions are available.
3050-
3051-Created September 12, 2009 Vasil Dimov
3052-*****************************************************************************/
3053-
3054-int
3055-main(int argc, char** argv)
3056-{
3057- long x;
3058- long y;
3059- long res;
3060- char c;
3061-
3062- x = 10;
3063- y = 123;
3064- res = __sync_bool_compare_and_swap(&x, x, y);
3065- if (!res || x != y) {
3066- return(1);
3067- }
3068-
3069- x = 10;
3070- y = 123;
3071- res = __sync_bool_compare_and_swap(&x, x + 1, y);
3072- if (res || x != 10) {
3073- return(1);
3074- }
3075-
3076- x = 10;
3077- y = 123;
3078- res = __sync_add_and_fetch(&x, y);
3079- if (res != 123 + 10 || x != 123 + 10) {
3080- return(1);
3081- }
3082-
3083- c = 10;
3084- res = __sync_lock_test_and_set(&c, 123);
3085- if (res != 10 || c != 123) {
3086- return(1);
3087- }
3088-
3089- return(0);
3090-}
3091
3092=== removed file 'plugin/innobase/ut/ut0auxconf_have_solaris_atomics.c'
3093--- plugin/innobase/ut/ut0auxconf_have_solaris_atomics.c 2010-10-02 21:15:42 +0000
3094+++ plugin/innobase/ut/ut0auxconf_have_solaris_atomics.c 1970-01-01 00:00:00 +0000
3095@@ -1,39 +0,0 @@
3096-/*****************************************************************************
3097-
3098-Copyright (c) 2009, Innobase Oy. All Rights Reserved.
3099-
3100-This program is free software; you can redistribute it and/or modify it under
3101-the terms of the GNU General Public License as published by the Free Software
3102-Foundation; version 2 of the License.
3103-
3104-This program is distributed in the hope that it will be useful, but WITHOUT
3105-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
3106-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
3107-
3108-You should have received a copy of the GNU General Public License along with
3109-this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
3110-St, Fifth Floor, Boston, MA 02110-1301 USA
3111-
3112-*****************************************************************************/
3113-
3114-/*****************************************************************************
3115-If this program compiles, then Solaris libc atomic funcions are available.
3116-
3117-Created April 18, 2009 Vasil Dimov
3118-*****************************************************************************/
3119-#include <atomic.h>
3120-
3121-int
3122-main(int argc, char** argv)
3123-{
3124- ulong_t ulong = 0;
3125- uint32_t uint32 = 0;
3126- uint64_t uint64 = 0;
3127-
3128- atomic_cas_ulong(&ulong, 0, 1);
3129- atomic_cas_32(&uint32, 0, 1);
3130- atomic_cas_64(&uint64, 0, 1);
3131- atomic_add_long(&ulong, 0);
3132-
3133- return(0);
3134-}
3135
3136=== removed file 'plugin/innobase/ut/ut0auxconf_pause.c'
3137--- plugin/innobase/ut/ut0auxconf_pause.c 2010-10-02 21:15:42 +0000
3138+++ plugin/innobase/ut/ut0auxconf_pause.c 1970-01-01 00:00:00 +0000
3139@@ -1,32 +0,0 @@
3140-/*****************************************************************************
3141-
3142-Copyright (c) 2009, Innobase Oy. All Rights Reserved.
3143-
3144-This program is free software; you can redistribute it and/or modify it under
3145-the terms of the GNU General Public License as published by the Free Software
3146-Foundation; version 2 of the License.
3147-
3148-This program is distributed in the hope that it will be useful, but WITHOUT
3149-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
3150-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
3151-
3152-You should have received a copy of the GNU General Public License along with
3153-this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
3154-St, Fifth Floor, Boston, MA 02110-1301 USA
3155-
3156-*****************************************************************************/
3157-
3158-/*****************************************************************************
3159-If this program compiles and can be run and returns 0, then the pause
3160-instruction is available.
3161-
3162-Created Jul 21, 2009 Vasil Dimov
3163-*****************************************************************************/
3164-
3165-int
3166-main(int argc, char** argv)
3167-{
3168- __asm__ __volatile__ ("pause");
3169-
3170- return(0);
3171-}
3172
3173=== removed file 'plugin/innobase/ut/ut0auxconf_sizeof_pthread_t.c'
3174--- plugin/innobase/ut/ut0auxconf_sizeof_pthread_t.c 2010-10-02 21:15:42 +0000
3175+++ plugin/innobase/ut/ut0auxconf_sizeof_pthread_t.c 1970-01-01 00:00:00 +0000
3176@@ -1,35 +0,0 @@
3177-/*****************************************************************************
3178-
3179-Copyright (c) 2009, Innobase Oy. All Rights Reserved.
3180-
3181-This program is free software; you can redistribute it and/or modify it under
3182-the terms of the GNU General Public License as published by the Free Software
3183-Foundation; version 2 of the License.
3184-
3185-This program is distributed in the hope that it will be useful, but WITHOUT
3186-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
3187-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
3188-
3189-You should have received a copy of the GNU General Public License along with
3190-this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
3191-St, Fifth Floor, Boston, MA 02110-1301 USA
3192-
3193-*****************************************************************************/
3194-
3195-/*****************************************************************************
3196-This program should compile and when run, print a single line like:
3197-#define SIZEOF_PTHREAD_T %d
3198-
3199-Created April 18, 2009 Vasil Dimov
3200-*****************************************************************************/
3201-
3202-#include <stdio.h>
3203-#include <pthread.h>
3204-
3205-int
3206-main(int argc, char** argv)
3207-{
3208- printf("#define SIZEOF_PTHREAD_T %d\n", (int) sizeof(pthread_t));
3209-
3210- return(0);
3211-}
3212
3213=== modified file 'plugin/innobase/ut/ut0ut.c'
3214--- plugin/innobase/ut/ut0ut.c 2010-11-16 06:01:47 +0000
3215+++ plugin/innobase/ut/ut0ut.c 2010-12-07 14:26:13 +0000
3216@@ -711,6 +711,8 @@
3217 return("Lock structs have exhausted the buffer pool");
3218 case DB_FOREIGN_DUPLICATE_KEY:
3219 return("Foreign key activated with duplicate keys");
3220+ case DB_FOREIGN_EXCEED_MAX_CASCADE:
3221+ return("Foreign key cascade delete/update exceeds max depth");
3222 case DB_TOO_MANY_CONCURRENT_TRXS:
3223 return("Too many concurrent transactions");
3224 case DB_UNSUPPORTED:
3225
3226=== modified file 'po/POTFILES.in'
3227--- po/POTFILES.in 2010-12-05 07:48:35 +0000
3228+++ po/POTFILES.in 2010-12-07 14:26:13 +0000
3229@@ -69,7 +69,6 @@
3230 plugin/innobase/handler/ha_innodb.cc
3231 plugin/innobase/handler/replication_dictionary.cc
3232 plugin/innobase/pars/pars0grm.c
3233-plugin/innobase/ut/ut0auxconf_pause.c
3234 plugin/logging_gearman/logging_gearman.cc
3235 plugin/logging_query/logging_query.cc
3236 plugin/logging_stats/logging_stats.cc
3237
3238=== modified file 'tests/include/index_merge2.inc'
3239--- tests/include/index_merge2.inc 2009-06-16 03:01:29 +0000
3240+++ tests/include/index_merge2.inc 2010-12-07 14:26:13 +0000
3241@@ -182,3 +182,56 @@
3242 explain select * from t1 where (key3 > 30 and key3<35) or (key2 >32 and key2 < 40);
3243 select * from t1 where (key3 > 30 and key3<35) or (key2 >32 and key2 < 40);
3244 drop table t1;
3245+
3246+--echo #
3247+--echo # Bug#56423: Different count with SELECT and CREATE SELECT queries
3248+--echo #
3249+
3250+CREATE TABLE t1 (
3251+ a INT,
3252+ b INT,
3253+ c INT,
3254+ d INT,
3255+ PRIMARY KEY (a),
3256+ KEY (c),
3257+ KEY bd (b,d)
3258+);
3259+
3260+INSERT INTO t1 VALUES
3261+(1, 0, 1, 0),
3262+(2, 1, 1, 1),
3263+(3, 1, 1, 1),
3264+(4, 0, 1, 1);
3265+
3266+EXPLAIN
3267+SELECT a
3268+FROM t1
3269+WHERE c = 1 AND b = 1 AND d = 1;
3270+
3271+CREATE TABLE t2 ( a INT )
3272+SELECT a
3273+FROM t1
3274+WHERE c = 1 AND b = 1 AND d = 1;
3275+
3276+SELECT * FROM t2;
3277+
3278+DROP TABLE t1, t2;
3279+
3280+CREATE TABLE t1( a INT, b INT, KEY(a), KEY(b) );
3281+INSERT INTO t1 VALUES (1, 2), (1, 2), (1, 2), (1, 2);
3282+SELECT * FROM t1 FORCE INDEX(a, b) WHERE a = 1 AND b = 2;
3283+
3284+DROP TABLE t1;
3285+
3286+--echo # Code coverage of fix.
3287+CREATE TABLE t1 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT);
3288+INSERT INTO t1 (b) VALUES (1);
3289+UPDATE t1 SET b = 2 WHERE a = 1;
3290+SELECT * FROM t1;
3291+
3292+CREATE TABLE t2 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b VARCHAR(1) );
3293+INSERT INTO t2 (b) VALUES ('a');
3294+UPDATE t2 SET b = 'b' WHERE a = 1;
3295+SELECT * FROM t2;
3296+
3297+DROP TABLE t1, t2;

Subscribers

People subscribed via source and target branches