Merge lp:~percona-toolkit-dev/percona-toolkit/fix-deep-recursion-bug-1136559 into lp:~percona-toolkit-dev/percona-toolkit/release-2.2.4

Proposed by Daniel Nichter
Status: Merged
Merged at revision: 586
Proposed branch: lp:~percona-toolkit-dev/percona-toolkit/fix-deep-recursion-bug-1136559
Merge into: lp:~percona-toolkit-dev/percona-toolkit/release-2.2.4
Diff against target: 854 lines (+510/-268)
8 files modified
bin/pt-duplicate-key-checker (+57/-52)
bin/pt-index-usage (+57/-52)
bin/pt-table-checksum (+57/-52)
bin/pt-table-sync (+57/-52)
lib/SchemaIterator.pm (+61/-58)
t/lib/SchemaIterator.t (+16/-2)
t/lib/samples/100-dbs-drop.sql (+100/-0)
t/lib/samples/100-dbs.sql (+105/-0)
To merge this branch: bzr merge lp:~percona-toolkit-dev/percona-toolkit/fix-deep-recursion-bug-1136559
Reviewer Review Type Date Requested Status
Daniel Nichter Approve
Review via email: mp+171435@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Daniel Nichter (daniel-nichter) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/pt-duplicate-key-checker'
2--- bin/pt-duplicate-key-checker 2013-06-25 22:32:19 +0000
3+++ bin/pt-duplicate-key-checker 2013-06-25 23:35:31 +0000
4@@ -3297,58 +3297,63 @@
5 $self->{dbs} = \@dbs;
6 }
7
8- if ( !$self->{db} ) {
9- $self->{db} = shift @{$self->{dbs}};
10- PTDEBUG && _d('Next database:', $self->{db});
11- return unless $self->{db};
12- }
13-
14- if ( !defined $self->{tbls} ) {
15- my $sql = 'SHOW /*!50002 FULL*/ TABLES FROM ' . $q->quote($self->{db});
16- PTDEBUG && _d($sql);
17- my @tbls = map {
18- $_->[0]; # (tbl, type)
19- }
20- grep {
21- my ($tbl, $type) = @$_;
22- (!$type || ($type ne 'VIEW'))
23- && $self->_resume_from_table($tbl)
24- && $self->table_is_allowed($self->{db}, $tbl);
25- }
26- @{$dbh->selectall_arrayref($sql)};
27- PTDEBUG && _d('Found', scalar @tbls, 'tables in database', $self->{db});
28- $self->{tbls} = \@tbls;
29- }
30-
31- while ( my $tbl = shift @{$self->{tbls}} ) {
32- my $ddl = eval { $tp->get_create_table($dbh, $self->{db}, $tbl) };
33- if ( my $e = $EVAL_ERROR ) {
34- my $table_name = "$self->{db}.$tbl";
35- if ( $e =~ /\QTable '$table_name' doesn't exist/ ) {
36- PTDEBUG && _d("Skipping $table_name because it no longer exists");
37- }
38- else {
39- warn "Skipping $table_name because SHOW CREATE TABLE failed: $e";
40- }
41- next;
42- }
43- my $tbl_struct = $tp->parse($ddl);
44- if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
45- return {
46- db => $self->{db},
47- tbl => $tbl,
48- name => $q->quote($self->{db}, $tbl),
49- ddl => $ddl,
50- tbl_struct => $tbl_struct,
51- };
52- }
53- }
54-
55- PTDEBUG && _d('No more tables in database', $self->{db});
56- $self->{db} = undef;
57- $self->{tbls} = undef;
58-
59- return $self->_iterate_dbh();
60+ DATABASE:
61+ while ( $self->{db} || defined(my $db = shift @{$self->{dbs}}) ) {
62+ if ( !$self->{db} ) {
63+ PTDEBUG && _d('Next database:', $db);
64+ $self->{db} = $db;
65+ }
66+
67+ if ( !$self->{tbls} ) {
68+ my $sql = 'SHOW /*!50002 FULL*/ TABLES FROM ' . $q->quote($self->{db});
69+ PTDEBUG && _d($sql);
70+ my @tbls = map {
71+ $_->[0]; # (tbl, type)
72+ }
73+ grep {
74+ my ($tbl, $type) = @$_;
75+ (!$type || ($type ne 'VIEW'))
76+ && $self->_resume_from_table($tbl)
77+ && $self->table_is_allowed($self->{db}, $tbl);
78+ }
79+ @{$dbh->selectall_arrayref($sql)};
80+ PTDEBUG && _d('Found', scalar @tbls, 'tables in database',$self->{db});
81+ $self->{tbls} = \@tbls;
82+ }
83+
84+ TABLE:
85+ while ( my $tbl = shift @{$self->{tbls}} ) {
86+ my $ddl = eval { $tp->get_create_table($dbh, $self->{db}, $tbl) };
87+ if ( my $e = $EVAL_ERROR ) {
88+ my $table_name = "$self->{db}.$tbl";
89+ if ( $e =~ /\QTable '$table_name' doesn't exist/ ) {
90+ PTDEBUG && _d("$table_name no longer exists");
91+ }
92+ else {
93+ warn "Skipping $table_name because SHOW CREATE TABLE failed: $e";
94+ }
95+ next TABLE;
96+ }
97+
98+ my $tbl_struct = $tp->parse($ddl);
99+ if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
100+ return {
101+ db => $self->{db},
102+ tbl => $tbl,
103+ name => $q->quote($self->{db}, $tbl),
104+ ddl => $ddl,
105+ tbl_struct => $tbl_struct,
106+ };
107+ }
108+ }
109+
110+ PTDEBUG && _d('No more tables in database', $self->{db});
111+ $self->{db} = undef;
112+ $self->{tbls} = undef;
113+ } # DATABASE
114+
115+ PTDEBUG && _d('No more databases');
116+ return;
117 }
118
119 sub database_is_allowed {
120
121=== modified file 'bin/pt-index-usage'
122--- bin/pt-index-usage 2013-06-25 22:32:19 +0000
123+++ bin/pt-index-usage 2013-06-25 23:35:31 +0000
124@@ -4131,58 +4131,63 @@
125 $self->{dbs} = \@dbs;
126 }
127
128- if ( !$self->{db} ) {
129- $self->{db} = shift @{$self->{dbs}};
130- PTDEBUG && _d('Next database:', $self->{db});
131- return unless $self->{db};
132- }
133-
134- if ( !defined $self->{tbls} ) {
135- my $sql = 'SHOW /*!50002 FULL*/ TABLES FROM ' . $q->quote($self->{db});
136- PTDEBUG && _d($sql);
137- my @tbls = map {
138- $_->[0]; # (tbl, type)
139- }
140- grep {
141- my ($tbl, $type) = @$_;
142- (!$type || ($type ne 'VIEW'))
143- && $self->_resume_from_table($tbl)
144- && $self->table_is_allowed($self->{db}, $tbl);
145- }
146- @{$dbh->selectall_arrayref($sql)};
147- PTDEBUG && _d('Found', scalar @tbls, 'tables in database', $self->{db});
148- $self->{tbls} = \@tbls;
149- }
150-
151- while ( my $tbl = shift @{$self->{tbls}} ) {
152- my $ddl = eval { $tp->get_create_table($dbh, $self->{db}, $tbl) };
153- if ( my $e = $EVAL_ERROR ) {
154- my $table_name = "$self->{db}.$tbl";
155- if ( $e =~ /\QTable '$table_name' doesn't exist/ ) {
156- PTDEBUG && _d("Skipping $table_name because it no longer exists");
157- }
158- else {
159- warn "Skipping $table_name because SHOW CREATE TABLE failed: $e";
160- }
161- next;
162- }
163- my $tbl_struct = $tp->parse($ddl);
164- if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
165- return {
166- db => $self->{db},
167- tbl => $tbl,
168- name => $q->quote($self->{db}, $tbl),
169- ddl => $ddl,
170- tbl_struct => $tbl_struct,
171- };
172- }
173- }
174-
175- PTDEBUG && _d('No more tables in database', $self->{db});
176- $self->{db} = undef;
177- $self->{tbls} = undef;
178-
179- return $self->_iterate_dbh();
180+ DATABASE:
181+ while ( $self->{db} || defined(my $db = shift @{$self->{dbs}}) ) {
182+ if ( !$self->{db} ) {
183+ PTDEBUG && _d('Next database:', $db);
184+ $self->{db} = $db;
185+ }
186+
187+ if ( !$self->{tbls} ) {
188+ my $sql = 'SHOW /*!50002 FULL*/ TABLES FROM ' . $q->quote($self->{db});
189+ PTDEBUG && _d($sql);
190+ my @tbls = map {
191+ $_->[0]; # (tbl, type)
192+ }
193+ grep {
194+ my ($tbl, $type) = @$_;
195+ (!$type || ($type ne 'VIEW'))
196+ && $self->_resume_from_table($tbl)
197+ && $self->table_is_allowed($self->{db}, $tbl);
198+ }
199+ @{$dbh->selectall_arrayref($sql)};
200+ PTDEBUG && _d('Found', scalar @tbls, 'tables in database',$self->{db});
201+ $self->{tbls} = \@tbls;
202+ }
203+
204+ TABLE:
205+ while ( my $tbl = shift @{$self->{tbls}} ) {
206+ my $ddl = eval { $tp->get_create_table($dbh, $self->{db}, $tbl) };
207+ if ( my $e = $EVAL_ERROR ) {
208+ my $table_name = "$self->{db}.$tbl";
209+ if ( $e =~ /\QTable '$table_name' doesn't exist/ ) {
210+ PTDEBUG && _d("$table_name no longer exists");
211+ }
212+ else {
213+ warn "Skipping $table_name because SHOW CREATE TABLE failed: $e";
214+ }
215+ next TABLE;
216+ }
217+
218+ my $tbl_struct = $tp->parse($ddl);
219+ if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
220+ return {
221+ db => $self->{db},
222+ tbl => $tbl,
223+ name => $q->quote($self->{db}, $tbl),
224+ ddl => $ddl,
225+ tbl_struct => $tbl_struct,
226+ };
227+ }
228+ }
229+
230+ PTDEBUG && _d('No more tables in database', $self->{db});
231+ $self->{db} = undef;
232+ $self->{tbls} = undef;
233+ } # DATABASE
234+
235+ PTDEBUG && _d('No more databases');
236+ return;
237 }
238
239 sub database_is_allowed {
240
241=== modified file 'bin/pt-table-checksum'
242--- bin/pt-table-checksum 2013-06-25 22:32:19 +0000
243+++ bin/pt-table-checksum 2013-06-25 23:35:31 +0000
244@@ -7344,58 +7344,63 @@
245 $self->{dbs} = \@dbs;
246 }
247
248- if ( !$self->{db} ) {
249- $self->{db} = shift @{$self->{dbs}};
250- PTDEBUG && _d('Next database:', $self->{db});
251- return unless $self->{db};
252- }
253-
254- if ( !defined $self->{tbls} ) {
255- my $sql = 'SHOW /*!50002 FULL*/ TABLES FROM ' . $q->quote($self->{db});
256- PTDEBUG && _d($sql);
257- my @tbls = map {
258- $_->[0]; # (tbl, type)
259- }
260- grep {
261- my ($tbl, $type) = @$_;
262- (!$type || ($type ne 'VIEW'))
263- && $self->_resume_from_table($tbl)
264- && $self->table_is_allowed($self->{db}, $tbl);
265- }
266- @{$dbh->selectall_arrayref($sql)};
267- PTDEBUG && _d('Found', scalar @tbls, 'tables in database', $self->{db});
268- $self->{tbls} = \@tbls;
269- }
270-
271- while ( my $tbl = shift @{$self->{tbls}} ) {
272- my $ddl = eval { $tp->get_create_table($dbh, $self->{db}, $tbl) };
273- if ( my $e = $EVAL_ERROR ) {
274- my $table_name = "$self->{db}.$tbl";
275- if ( $e =~ /\QTable '$table_name' doesn't exist/ ) {
276- PTDEBUG && _d("Skipping $table_name because it no longer exists");
277- }
278- else {
279- warn "Skipping $table_name because SHOW CREATE TABLE failed: $e";
280- }
281- next;
282- }
283- my $tbl_struct = $tp->parse($ddl);
284- if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
285- return {
286- db => $self->{db},
287- tbl => $tbl,
288- name => $q->quote($self->{db}, $tbl),
289- ddl => $ddl,
290- tbl_struct => $tbl_struct,
291- };
292- }
293- }
294-
295- PTDEBUG && _d('No more tables in database', $self->{db});
296- $self->{db} = undef;
297- $self->{tbls} = undef;
298-
299- return $self->_iterate_dbh();
300+ DATABASE:
301+ while ( $self->{db} || defined(my $db = shift @{$self->{dbs}}) ) {
302+ if ( !$self->{db} ) {
303+ PTDEBUG && _d('Next database:', $db);
304+ $self->{db} = $db;
305+ }
306+
307+ if ( !$self->{tbls} ) {
308+ my $sql = 'SHOW /*!50002 FULL*/ TABLES FROM ' . $q->quote($self->{db});
309+ PTDEBUG && _d($sql);
310+ my @tbls = map {
311+ $_->[0]; # (tbl, type)
312+ }
313+ grep {
314+ my ($tbl, $type) = @$_;
315+ (!$type || ($type ne 'VIEW'))
316+ && $self->_resume_from_table($tbl)
317+ && $self->table_is_allowed($self->{db}, $tbl);
318+ }
319+ @{$dbh->selectall_arrayref($sql)};
320+ PTDEBUG && _d('Found', scalar @tbls, 'tables in database',$self->{db});
321+ $self->{tbls} = \@tbls;
322+ }
323+
324+ TABLE:
325+ while ( my $tbl = shift @{$self->{tbls}} ) {
326+ my $ddl = eval { $tp->get_create_table($dbh, $self->{db}, $tbl) };
327+ if ( my $e = $EVAL_ERROR ) {
328+ my $table_name = "$self->{db}.$tbl";
329+ if ( $e =~ /\QTable '$table_name' doesn't exist/ ) {
330+ PTDEBUG && _d("$table_name no longer exists");
331+ }
332+ else {
333+ warn "Skipping $table_name because SHOW CREATE TABLE failed: $e";
334+ }
335+ next TABLE;
336+ }
337+
338+ my $tbl_struct = $tp->parse($ddl);
339+ if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
340+ return {
341+ db => $self->{db},
342+ tbl => $tbl,
343+ name => $q->quote($self->{db}, $tbl),
344+ ddl => $ddl,
345+ tbl_struct => $tbl_struct,
346+ };
347+ }
348+ }
349+
350+ PTDEBUG && _d('No more tables in database', $self->{db});
351+ $self->{db} = undef;
352+ $self->{tbls} = undef;
353+ } # DATABASE
354+
355+ PTDEBUG && _d('No more databases');
356+ return;
357 }
358
359 sub database_is_allowed {
360
361=== modified file 'bin/pt-table-sync'
362--- bin/pt-table-sync 2013-06-25 22:32:19 +0000
363+++ bin/pt-table-sync 2013-06-25 23:35:31 +0000
364@@ -7690,58 +7690,63 @@
365 $self->{dbs} = \@dbs;
366 }
367
368- if ( !$self->{db} ) {
369- $self->{db} = shift @{$self->{dbs}};
370- PTDEBUG && _d('Next database:', $self->{db});
371- return unless $self->{db};
372- }
373-
374- if ( !defined $self->{tbls} ) {
375- my $sql = 'SHOW /*!50002 FULL*/ TABLES FROM ' . $q->quote($self->{db});
376- PTDEBUG && _d($sql);
377- my @tbls = map {
378- $_->[0]; # (tbl, type)
379- }
380- grep {
381- my ($tbl, $type) = @$_;
382- (!$type || ($type ne 'VIEW'))
383- && $self->_resume_from_table($tbl)
384- && $self->table_is_allowed($self->{db}, $tbl);
385- }
386- @{$dbh->selectall_arrayref($sql)};
387- PTDEBUG && _d('Found', scalar @tbls, 'tables in database', $self->{db});
388- $self->{tbls} = \@tbls;
389- }
390-
391- while ( my $tbl = shift @{$self->{tbls}} ) {
392- my $ddl = eval { $tp->get_create_table($dbh, $self->{db}, $tbl) };
393- if ( my $e = $EVAL_ERROR ) {
394- my $table_name = "$self->{db}.$tbl";
395- if ( $e =~ /\QTable '$table_name' doesn't exist/ ) {
396- PTDEBUG && _d("Skipping $table_name because it no longer exists");
397- }
398- else {
399- warn "Skipping $table_name because SHOW CREATE TABLE failed: $e";
400- }
401- next;
402- }
403- my $tbl_struct = $tp->parse($ddl);
404- if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
405- return {
406- db => $self->{db},
407- tbl => $tbl,
408- name => $q->quote($self->{db}, $tbl),
409- ddl => $ddl,
410- tbl_struct => $tbl_struct,
411- };
412- }
413- }
414-
415- PTDEBUG && _d('No more tables in database', $self->{db});
416- $self->{db} = undef;
417- $self->{tbls} = undef;
418-
419- return $self->_iterate_dbh();
420+ DATABASE:
421+ while ( $self->{db} || defined(my $db = shift @{$self->{dbs}}) ) {
422+ if ( !$self->{db} ) {
423+ PTDEBUG && _d('Next database:', $db);
424+ $self->{db} = $db;
425+ }
426+
427+ if ( !$self->{tbls} ) {
428+ my $sql = 'SHOW /*!50002 FULL*/ TABLES FROM ' . $q->quote($self->{db});
429+ PTDEBUG && _d($sql);
430+ my @tbls = map {
431+ $_->[0]; # (tbl, type)
432+ }
433+ grep {
434+ my ($tbl, $type) = @$_;
435+ (!$type || ($type ne 'VIEW'))
436+ && $self->_resume_from_table($tbl)
437+ && $self->table_is_allowed($self->{db}, $tbl);
438+ }
439+ @{$dbh->selectall_arrayref($sql)};
440+ PTDEBUG && _d('Found', scalar @tbls, 'tables in database',$self->{db});
441+ $self->{tbls} = \@tbls;
442+ }
443+
444+ TABLE:
445+ while ( my $tbl = shift @{$self->{tbls}} ) {
446+ my $ddl = eval { $tp->get_create_table($dbh, $self->{db}, $tbl) };
447+ if ( my $e = $EVAL_ERROR ) {
448+ my $table_name = "$self->{db}.$tbl";
449+ if ( $e =~ /\QTable '$table_name' doesn't exist/ ) {
450+ PTDEBUG && _d("$table_name no longer exists");
451+ }
452+ else {
453+ warn "Skipping $table_name because SHOW CREATE TABLE failed: $e";
454+ }
455+ next TABLE;
456+ }
457+
458+ my $tbl_struct = $tp->parse($ddl);
459+ if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
460+ return {
461+ db => $self->{db},
462+ tbl => $tbl,
463+ name => $q->quote($self->{db}, $tbl),
464+ ddl => $ddl,
465+ tbl_struct => $tbl_struct,
466+ };
467+ }
468+ }
469+
470+ PTDEBUG && _d('No more tables in database', $self->{db});
471+ $self->{db} = undef;
472+ $self->{tbls} = undef;
473+ } # DATABASE
474+
475+ PTDEBUG && _d('No more databases');
476+ return;
477 }
478
479 sub database_is_allowed {
480
481=== modified file 'lib/SchemaIterator.pm'
482--- lib/SchemaIterator.pm 2013-01-03 00:19:16 +0000
483+++ lib/SchemaIterator.pm 2013-06-25 23:35:31 +0000
484@@ -334,64 +334,67 @@
485 $self->{dbs} = \@dbs;
486 }
487
488- if ( !$self->{db} ) {
489- $self->{db} = shift @{$self->{dbs}};
490- PTDEBUG && _d('Next database:', $self->{db});
491- return unless $self->{db};
492- }
493-
494- if ( !defined $self->{tbls} ) {
495- my $sql = 'SHOW /*!50002 FULL*/ TABLES FROM ' . $q->quote($self->{db});
496- PTDEBUG && _d($sql);
497- my @tbls = map {
498- $_->[0]; # (tbl, type)
499- }
500- grep {
501- my ($tbl, $type) = @$_;
502- (!$type || ($type ne 'VIEW'))
503- && $self->_resume_from_table($tbl)
504- && $self->table_is_allowed($self->{db}, $tbl);
505- }
506- @{$dbh->selectall_arrayref($sql)};
507- PTDEBUG && _d('Found', scalar @tbls, 'tables in database', $self->{db});
508- $self->{tbls} = \@tbls;
509- }
510-
511- while ( my $tbl = shift @{$self->{tbls}} ) {
512- my $ddl = eval { $tp->get_create_table($dbh, $self->{db}, $tbl) };
513- if ( my $e = $EVAL_ERROR ) {
514- my $table_name = "$self->{db}.$tbl";
515- # SHOW CREATE TABLE failed. This is a bit puzzling;
516- # maybe the table got dropped, or crashed. Not much we can
517- # do about it; If the table is missing, just PTDEBUG it, but
518- # otherwise, warn with the error.
519- if ( $e =~ /\QTable '$table_name' doesn't exist/ ) {
520- PTDEBUG && _d("Skipping $table_name because it no longer exists");
521- }
522- else {
523- warn "Skipping $table_name because SHOW CREATE TABLE failed: $e";
524- }
525- next;
526- }
527- my $tbl_struct = $tp->parse($ddl);
528- if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
529- return {
530- db => $self->{db},
531- tbl => $tbl,
532- name => $q->quote($self->{db}, $tbl),
533- ddl => $ddl,
534- tbl_struct => $tbl_struct,
535- };
536- }
537- }
538-
539- PTDEBUG && _d('No more tables in database', $self->{db});
540- $self->{db} = undef;
541- $self->{tbls} = undef;
542-
543- # Recurse to get the next database. If there's no next db, then the
544- # call will return undef and we'll return undef, too.
545- return $self->_iterate_dbh();
546+ DATABASE:
547+ while ( $self->{db} || defined(my $db = shift @{$self->{dbs}}) ) {
548+ if ( !$self->{db} ) {
549+ PTDEBUG && _d('Next database:', $db);
550+ $self->{db} = $db;
551+ }
552+
553+ if ( !$self->{tbls} ) {
554+ my $sql = 'SHOW /*!50002 FULL*/ TABLES FROM ' . $q->quote($self->{db});
555+ PTDEBUG && _d($sql);
556+ my @tbls = map {
557+ $_->[0]; # (tbl, type)
558+ }
559+ grep {
560+ my ($tbl, $type) = @$_;
561+ (!$type || ($type ne 'VIEW'))
562+ && $self->_resume_from_table($tbl)
563+ && $self->table_is_allowed($self->{db}, $tbl);
564+ }
565+ @{$dbh->selectall_arrayref($sql)};
566+ PTDEBUG && _d('Found', scalar @tbls, 'tables in database',$self->{db});
567+ $self->{tbls} = \@tbls;
568+ }
569+
570+ TABLE:
571+ while ( my $tbl = shift @{$self->{tbls}} ) {
572+ my $ddl = eval { $tp->get_create_table($dbh, $self->{db}, $tbl) };
573+ if ( my $e = $EVAL_ERROR ) {
574+ my $table_name = "$self->{db}.$tbl";
575+ # SHOW CREATE TABLE failed. This is a bit puzzling;
576+ # maybe the table got dropped, or crashed. Not much we can
577+ # do about it; If the table is missing, just PTDEBUG it, but
578+ # otherwise, warn with the error.
579+ if ( $e =~ /\QTable '$table_name' doesn't exist/ ) {
580+ PTDEBUG && _d("$table_name no longer exists");
581+ }
582+ else {
583+ warn "Skipping $table_name because SHOW CREATE TABLE failed: $e";
584+ }
585+ next TABLE;
586+ }
587+
588+ my $tbl_struct = $tp->parse($ddl);
589+ if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
590+ return {
591+ db => $self->{db},
592+ tbl => $tbl,
593+ name => $q->quote($self->{db}, $tbl),
594+ ddl => $ddl,
595+ tbl_struct => $tbl_struct,
596+ };
597+ }
598+ }
599+
600+ PTDEBUG && _d('No more tables in database', $self->{db});
601+ $self->{db} = undef;
602+ $self->{tbls} = undef;
603+ } # DATABASE
604+
605+ PTDEBUG && _d('No more databases');
606+ return;
607 }
608
609 sub database_is_allowed {
610
611=== modified file 't/lib/SchemaIterator.t'
612--- t/lib/SchemaIterator.t 2012-12-07 18:52:33 +0000
613+++ t/lib/SchemaIterator.t 2013-06-25 23:35:31 +0000
614@@ -548,9 +548,23 @@
615 diag(`$trunk/sandbox/stop-sandbox $master3_port >/dev/null`);
616
617 # #############################################################################
618+# Bug 1136559: Deep recursion on subroutine "SchemaIterator::_iterate_dbh"
619+# #############################################################################
620+
621+$sb->wipe_clean($dbh);
622+diag(`/tmp/12345/use < $trunk/t/lib/samples/100-dbs.sql`);
623+
624+test_so(
625+ filters => [],
626+ result => "foo001.bar001 ",
627+ lives_ok => 1,
628+ test_name => "Bug 1136559: Deep recursion on subroutine SchemaIterator::_iterate_dbh",
629+);
630+
631+diag(`/tmp/12345/use < $trunk/t/lib/samples/100-dbs-drop.sql`);
632+
633+# #############################################################################
634 # Done.
635 # #############################################################################
636 ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
637-
638 done_testing;
639-exit;
640
641=== added file 't/lib/samples/100-dbs-drop.sql'
642--- t/lib/samples/100-dbs-drop.sql 1970-01-01 00:00:00 +0000
643+++ t/lib/samples/100-dbs-drop.sql 2013-06-25 23:35:31 +0000
644@@ -0,0 +1,100 @@
645+DROP DATABASE IF EXISTS foo001;
646+DROP DATABASE IF EXISTS foo002;
647+DROP DATABASE IF EXISTS foo003;
648+DROP DATABASE IF EXISTS foo004;
649+DROP DATABASE IF EXISTS foo005;
650+DROP DATABASE IF EXISTS foo006;
651+DROP DATABASE IF EXISTS foo007;
652+DROP DATABASE IF EXISTS foo008;
653+DROP DATABASE IF EXISTS foo009;
654+DROP DATABASE IF EXISTS foo010;
655+DROP DATABASE IF EXISTS foo011;
656+DROP DATABASE IF EXISTS foo012;
657+DROP DATABASE IF EXISTS foo013;
658+DROP DATABASE IF EXISTS foo014;
659+DROP DATABASE IF EXISTS foo015;
660+DROP DATABASE IF EXISTS foo016;
661+DROP DATABASE IF EXISTS foo017;
662+DROP DATABASE IF EXISTS foo018;
663+DROP DATABASE IF EXISTS foo019;
664+DROP DATABASE IF EXISTS foo020;
665+DROP DATABASE IF EXISTS foo021;
666+DROP DATABASE IF EXISTS foo022;
667+DROP DATABASE IF EXISTS foo023;
668+DROP DATABASE IF EXISTS foo024;
669+DROP DATABASE IF EXISTS foo025;
670+DROP DATABASE IF EXISTS foo026;
671+DROP DATABASE IF EXISTS foo027;
672+DROP DATABASE IF EXISTS foo028;
673+DROP DATABASE IF EXISTS foo029;
674+DROP DATABASE IF EXISTS foo030;
675+DROP DATABASE IF EXISTS foo031;
676+DROP DATABASE IF EXISTS foo032;
677+DROP DATABASE IF EXISTS foo033;
678+DROP DATABASE IF EXISTS foo034;
679+DROP DATABASE IF EXISTS foo035;
680+DROP DATABASE IF EXISTS foo036;
681+DROP DATABASE IF EXISTS foo037;
682+DROP DATABASE IF EXISTS foo038;
683+DROP DATABASE IF EXISTS foo039;
684+DROP DATABASE IF EXISTS foo040;
685+DROP DATABASE IF EXISTS foo041;
686+DROP DATABASE IF EXISTS foo042;
687+DROP DATABASE IF EXISTS foo043;
688+DROP DATABASE IF EXISTS foo044;
689+DROP DATABASE IF EXISTS foo045;
690+DROP DATABASE IF EXISTS foo046;
691+DROP DATABASE IF EXISTS foo047;
692+DROP DATABASE IF EXISTS foo048;
693+DROP DATABASE IF EXISTS foo049;
694+DROP DATABASE IF EXISTS foo050;
695+DROP DATABASE IF EXISTS foo051;
696+DROP DATABASE IF EXISTS foo052;
697+DROP DATABASE IF EXISTS foo053;
698+DROP DATABASE IF EXISTS foo054;
699+DROP DATABASE IF EXISTS foo055;
700+DROP DATABASE IF EXISTS foo056;
701+DROP DATABASE IF EXISTS foo057;
702+DROP DATABASE IF EXISTS foo058;
703+DROP DATABASE IF EXISTS foo059;
704+DROP DATABASE IF EXISTS foo060;
705+DROP DATABASE IF EXISTS foo061;
706+DROP DATABASE IF EXISTS foo062;
707+DROP DATABASE IF EXISTS foo063;
708+DROP DATABASE IF EXISTS foo064;
709+DROP DATABASE IF EXISTS foo065;
710+DROP DATABASE IF EXISTS foo066;
711+DROP DATABASE IF EXISTS foo067;
712+DROP DATABASE IF EXISTS foo068;
713+DROP DATABASE IF EXISTS foo069;
714+DROP DATABASE IF EXISTS foo070;
715+DROP DATABASE IF EXISTS foo071;
716+DROP DATABASE IF EXISTS foo072;
717+DROP DATABASE IF EXISTS foo073;
718+DROP DATABASE IF EXISTS foo074;
719+DROP DATABASE IF EXISTS foo075;
720+DROP DATABASE IF EXISTS foo076;
721+DROP DATABASE IF EXISTS foo077;
722+DROP DATABASE IF EXISTS foo078;
723+DROP DATABASE IF EXISTS foo079;
724+DROP DATABASE IF EXISTS foo080;
725+DROP DATABASE IF EXISTS foo081;
726+DROP DATABASE IF EXISTS foo082;
727+DROP DATABASE IF EXISTS foo083;
728+DROP DATABASE IF EXISTS foo084;
729+DROP DATABASE IF EXISTS foo085;
730+DROP DATABASE IF EXISTS foo086;
731+DROP DATABASE IF EXISTS foo087;
732+DROP DATABASE IF EXISTS foo088;
733+DROP DATABASE IF EXISTS foo089;
734+DROP DATABASE IF EXISTS foo090;
735+DROP DATABASE IF EXISTS foo091;
736+DROP DATABASE IF EXISTS foo092;
737+DROP DATABASE IF EXISTS foo093;
738+DROP DATABASE IF EXISTS foo094;
739+DROP DATABASE IF EXISTS foo095;
740+DROP DATABASE IF EXISTS foo096;
741+DROP DATABASE IF EXISTS foo097;
742+DROP DATABASE IF EXISTS foo098;
743+DROP DATABASE IF EXISTS foo099;
744+DROP DATABASE IF EXISTS foo100;
745
746=== added file 't/lib/samples/100-dbs.sql'
747--- t/lib/samples/100-dbs.sql 1970-01-01 00:00:00 +0000
748+++ t/lib/samples/100-dbs.sql 2013-06-25 23:35:31 +0000
749@@ -0,0 +1,105 @@
750+CREATE DATABASE IF NOT EXISTS foo001;
751+CREATE DATABASE IF NOT EXISTS foo002;
752+CREATE DATABASE IF NOT EXISTS foo003;
753+CREATE DATABASE IF NOT EXISTS foo004;
754+CREATE DATABASE IF NOT EXISTS foo005;
755+CREATE DATABASE IF NOT EXISTS foo006;
756+CREATE DATABASE IF NOT EXISTS foo007;
757+CREATE DATABASE IF NOT EXISTS foo008;
758+CREATE DATABASE IF NOT EXISTS foo009;
759+CREATE DATABASE IF NOT EXISTS foo010;
760+CREATE DATABASE IF NOT EXISTS foo011;
761+CREATE DATABASE IF NOT EXISTS foo012;
762+CREATE DATABASE IF NOT EXISTS foo013;
763+CREATE DATABASE IF NOT EXISTS foo014;
764+CREATE DATABASE IF NOT EXISTS foo015;
765+CREATE DATABASE IF NOT EXISTS foo016;
766+CREATE DATABASE IF NOT EXISTS foo017;
767+CREATE DATABASE IF NOT EXISTS foo018;
768+CREATE DATABASE IF NOT EXISTS foo019;
769+CREATE DATABASE IF NOT EXISTS foo020;
770+CREATE DATABASE IF NOT EXISTS foo021;
771+CREATE DATABASE IF NOT EXISTS foo022;
772+CREATE DATABASE IF NOT EXISTS foo023;
773+CREATE DATABASE IF NOT EXISTS foo024;
774+CREATE DATABASE IF NOT EXISTS foo025;
775+CREATE DATABASE IF NOT EXISTS foo026;
776+CREATE DATABASE IF NOT EXISTS foo027;
777+CREATE DATABASE IF NOT EXISTS foo028;
778+CREATE DATABASE IF NOT EXISTS foo029;
779+CREATE DATABASE IF NOT EXISTS foo030;
780+CREATE DATABASE IF NOT EXISTS foo031;
781+CREATE DATABASE IF NOT EXISTS foo032;
782+CREATE DATABASE IF NOT EXISTS foo033;
783+CREATE DATABASE IF NOT EXISTS foo034;
784+CREATE DATABASE IF NOT EXISTS foo035;
785+CREATE DATABASE IF NOT EXISTS foo036;
786+CREATE DATABASE IF NOT EXISTS foo037;
787+CREATE DATABASE IF NOT EXISTS foo038;
788+CREATE DATABASE IF NOT EXISTS foo039;
789+CREATE DATABASE IF NOT EXISTS foo040;
790+CREATE DATABASE IF NOT EXISTS foo041;
791+CREATE DATABASE IF NOT EXISTS foo042;
792+CREATE DATABASE IF NOT EXISTS foo043;
793+CREATE DATABASE IF NOT EXISTS foo044;
794+CREATE DATABASE IF NOT EXISTS foo045;
795+CREATE DATABASE IF NOT EXISTS foo046;
796+CREATE DATABASE IF NOT EXISTS foo047;
797+CREATE DATABASE IF NOT EXISTS foo048;
798+CREATE DATABASE IF NOT EXISTS foo049;
799+CREATE DATABASE IF NOT EXISTS foo050;
800+CREATE DATABASE IF NOT EXISTS foo051;
801+CREATE DATABASE IF NOT EXISTS foo052;
802+CREATE DATABASE IF NOT EXISTS foo053;
803+CREATE DATABASE IF NOT EXISTS foo054;
804+CREATE DATABASE IF NOT EXISTS foo055;
805+CREATE DATABASE IF NOT EXISTS foo056;
806+CREATE DATABASE IF NOT EXISTS foo057;
807+CREATE DATABASE IF NOT EXISTS foo058;
808+CREATE DATABASE IF NOT EXISTS foo059;
809+CREATE DATABASE IF NOT EXISTS foo060;
810+CREATE DATABASE IF NOT EXISTS foo061;
811+CREATE DATABASE IF NOT EXISTS foo062;
812+CREATE DATABASE IF NOT EXISTS foo063;
813+CREATE DATABASE IF NOT EXISTS foo064;
814+CREATE DATABASE IF NOT EXISTS foo065;
815+CREATE DATABASE IF NOT EXISTS foo066;
816+CREATE DATABASE IF NOT EXISTS foo067;
817+CREATE DATABASE IF NOT EXISTS foo068;
818+CREATE DATABASE IF NOT EXISTS foo069;
819+CREATE DATABASE IF NOT EXISTS foo070;
820+CREATE DATABASE IF NOT EXISTS foo071;
821+CREATE DATABASE IF NOT EXISTS foo072;
822+CREATE DATABASE IF NOT EXISTS foo073;
823+CREATE DATABASE IF NOT EXISTS foo074;
824+CREATE DATABASE IF NOT EXISTS foo075;
825+CREATE DATABASE IF NOT EXISTS foo076;
826+CREATE DATABASE IF NOT EXISTS foo077;
827+CREATE DATABASE IF NOT EXISTS foo078;
828+CREATE DATABASE IF NOT EXISTS foo079;
829+CREATE DATABASE IF NOT EXISTS foo080;
830+CREATE DATABASE IF NOT EXISTS foo081;
831+CREATE DATABASE IF NOT EXISTS foo082;
832+CREATE DATABASE IF NOT EXISTS foo083;
833+CREATE DATABASE IF NOT EXISTS foo084;
834+CREATE DATABASE IF NOT EXISTS foo085;
835+CREATE DATABASE IF NOT EXISTS foo086;
836+CREATE DATABASE IF NOT EXISTS foo087;
837+CREATE DATABASE IF NOT EXISTS foo088;
838+CREATE DATABASE IF NOT EXISTS foo089;
839+CREATE DATABASE IF NOT EXISTS foo090;
840+CREATE DATABASE IF NOT EXISTS foo091;
841+CREATE DATABASE IF NOT EXISTS foo092;
842+CREATE DATABASE IF NOT EXISTS foo093;
843+CREATE DATABASE IF NOT EXISTS foo094;
844+CREATE DATABASE IF NOT EXISTS foo095;
845+CREATE DATABASE IF NOT EXISTS foo096;
846+CREATE DATABASE IF NOT EXISTS foo097;
847+CREATE DATABASE IF NOT EXISTS foo098;
848+CREATE DATABASE IF NOT EXISTS foo099;
849+CREATE DATABASE IF NOT EXISTS foo100;
850+CREATE TABLE IF NOT EXISTS foo001.bar001 (
851+ `id` int unsigned NOT NULL AUTO_INCREMENT,
852+ `value` varchar(255) NOT NULL,
853+ PRIMARY KEY (`id`)
854+) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Subscribers

People subscribed via source and target branches

to all changes: