9 # globally set for the rest of test
10 # the rowparser maker does not order its hashes by default for the miniscule
11 # speed gain. But it does not disable sorting either - for this test
12 # everything will be ordered nicely, and the hash randomization of 5.18
13 # will not trip up anything
15 $Data::Dumper::Sortkeys = 1;
17 my $schema = DBICTest->init_schema(no_deploy => 1);
19 single_track.cd.artist.name
24 $schema->source ('CD')->_mk_row_parser({
25 inflate_map => $infmap,
29 { single_track => ( ! defined( $_->[0]) )
50 'Simple 1:1 descending non-collapsing parser',
54 single_track.cd.artist.cds.tracks.title
55 single_track.cd.artist.artistid
57 single_track.cd.artist.cds.cdid
63 $schema->source ('CD')->_mk_row_parser({
64 inflate_map => $infmap,
67 { artist => $_->[5], title => $_->[4], year => $_->[2] },
69 single_track => ( (! defined $_->[0] ) && (! defined $_->[1]) && (! defined $_->[3] ) )
77 { artistid => $_->[1] },
79 cds => ( (! defined $_->[0] ) && ( ! defined $_->[3] ) )
83 tracks => ( ! defined $_->[0] )
84 ? bless ( [{ title => $_->[0] }], __NBC__ )
85 : [{ title => $_->[0] }]
91 tracks => ( ! defined $_->[0] )
92 ? bless ( [{ title => $_->[0] }], __NBC__ )
93 : [{ title => $_->[0] }]
109 { artistid => $_->[1] },
111 cds => ( (! defined $_->[0] ) && ( ! defined $_->[3] ) )
115 tracks => ( ! defined $_->[0] )
116 ? bless ( [{ title => $_->[0] }], __NBC__ )
117 : [{ title => $_->[0] }]
123 tracks => ( ! defined $_->[0] )
124 ? bless ( [{ title => $_->[0] }], __NBC__ )
125 : [{ title => $_->[0] }]
136 '1:1 descending non-collapsing parser terminating with chained 1:M:M',
140 $schema->source ('CD')->_mk_row_parser({
142 inflate_map => $infmap,
145 artist => $_->[5], title => $_->[4], year => $_->[2],
147 ( single_track => ( (! defined $_->[0] ) && (! defined $_->[1]) && (! defined $_->[3] ) )
154 ( cds => ( (! defined $_->[0] ) && ( ! defined $_->[3] ) )
158 ( tracks => ( ! defined $_->[0] )
160 : { title => $_->[0] }
169 '1:1 descending non-collapsing HRI-direct parser terminating with chained 1:M:M',
175 ($schema->source('CD')->_resolve_collapse({ as => {map { $infmap->[$_] => $_ } 0 .. $#$infmap} })),
177 -identifying_columns => [ 4, 5 ],
180 -identifying_columns => [ 1, 4, 5 ],
185 -identifying_columns => [ 1, 4, 5 ],
189 -identifying_columns => [ 1, 4, 5 ],
193 -identifying_columns => [ 1, 3, 4, 5 ],
197 -identifying_columns => [ 0, 1, 3, 4, 5 ],
205 'Correct collapse map for 1:1 descending chain terminating with chained 1:M:M'
209 $schema->source ('CD')->_mk_row_parser({
210 inflate_map => $infmap,
214 my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids);
216 while ($cur_row_data = (
217 ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } )
219 ( $_[1] and $_[1]->() )
222 $cur_row_ids{$_} = defined $cur_row_data->[$_] ? $cur_row_data->[$_] : "\0NULL\xFF$rows_pos\xFF$_\0"
225 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
226 $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}} and (unshift @{$_[2]}, $cur_row_data) and last;
228 # the rowdata itself for root node
229 $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}} ||= $_[0][$result_pos++] = [{ artist => $cur_row_data->[5], title => $cur_row_data->[4], year => $cur_row_data->[2] }];
231 # prefetch data of single_track (placed in root)
232 $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{single_track} ||= $collapse_idx[1]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}} = [];
233 defined($cur_row_data->[1]) or bless( $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{single_track}, __NBC__ );
235 # prefetch data of cd (placed in single_track)
236 $collapse_idx[1]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{cd} ||= $collapse_idx[2]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}} = [];
238 # prefetch data of artist ( placed in single_track->cd)
239 $collapse_idx[2]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{artist} ||= $collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}} = [{ artistid => $cur_row_data->[1] }];
241 # prefetch data of cds (if available)
242 (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} )
244 push @{$collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{cds}}, (
245 $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} = [{ cdid => $cur_row_data->[3] }]
247 defined($cur_row_data->[3]) or bless( $collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{cds}, __NBC__ );
249 # prefetch data of tracks (if available)
250 (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} )
252 push @{$collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{tracks}}, (
253 $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} = [{ title => $cur_row_data->[0] }]
255 defined($cur_row_data->[0]) or bless( $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{tracks}, __NBC__ );
258 $#{$_[0]} = $result_pos - 1;
260 'Same 1:1 descending terminating with chained 1:M:M but with collapse',
264 $schema->source ('CD')->_mk_row_parser({
265 inflate_map => $infmap,
270 my ($result_pos, @collapse_idx, $cur_row_data);
272 while ($cur_row_data = (
273 ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } )
275 ( $_[1] and $_[1]->() )
278 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
279 $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_data->[4]}{$cur_row_data->[5]} and (unshift @{$_[2]}, $cur_row_data) and last;
281 # the rowdata itself for root node
282 $collapse_idx[0]{$cur_row_data->[4]}{$cur_row_data->[5]} ||= $_[0][$result_pos++] = { artist => $cur_row_data->[5], title => $cur_row_data->[4], year => $cur_row_data->[2] };
284 # prefetch data of single_track (placed in root)
285 (! defined($cur_row_data->[1]) ) ? $collapse_idx[0]{$cur_row_data->[4]}{$cur_row_data->[5]}{single_track} = undef : do {
286 $collapse_idx[0]{$cur_row_data->[4]}{$cur_row_data->[5]}{single_track} ||= $collapse_idx[1]{$cur_row_data->[1]}{$cur_row_data->[4]}{$cur_row_data->[5]};
288 # prefetch data of cd (placed in single_track)
289 $collapse_idx[1]{$cur_row_data->[1]}{$cur_row_data->[4]}{$cur_row_data->[5]}{cd} ||= $collapse_idx[2]{$cur_row_data->[1]}{$cur_row_data->[4]}{$cur_row_data->[5]};
291 # prefetch data of artist ( placed in single_track->cd)
292 $collapse_idx[2]{$cur_row_data->[1]}{$cur_row_data->[4]}{$cur_row_data->[5]}{artist} ||= $collapse_idx[3]{$cur_row_data->[1]}{$cur_row_data->[4]}{$cur_row_data->[5]} = { artistid => $cur_row_data->[1] };
294 # prefetch data of cds (if available)
295 (! defined $cur_row_data->[3] ) ? $collapse_idx[3]{$cur_row_data->[1]}{$cur_row_data->[4]}{$cur_row_data->[5]}{cds} = [] : do {
297 (! $collapse_idx[4]{$cur_row_data->[1]}{$cur_row_data->[3]}{$cur_row_data->[4]}{$cur_row_data->[5]} )
299 push @{$collapse_idx[3]{$cur_row_data->[1]}{$cur_row_data->[4]}{$cur_row_data->[5]}{cds}}, (
300 $collapse_idx[4]{$cur_row_data->[1]}{$cur_row_data->[3]}{$cur_row_data->[4]}{$cur_row_data->[5]} = { cdid => $cur_row_data->[3] }
303 # prefetch data of tracks (if available)
304 ( ! defined $cur_row_data->[0] ) ? $collapse_idx[4]{$cur_row_data->[1]}{$cur_row_data->[3]}{$cur_row_data->[4]}{$cur_row_data->[5]}{tracks} = [] : do {
306 (! $collapse_idx[5]{$cur_row_data->[0]}{$cur_row_data->[1]}{$cur_row_data->[3]}{$cur_row_data->[4]}{$cur_row_data->[5]} )
308 push @{$collapse_idx[4]{$cur_row_data->[1]}{$cur_row_data->[3]}{$cur_row_data->[4]}{$cur_row_data->[5]}{tracks}}, (
309 $collapse_idx[5]{$cur_row_data->[0]}{$cur_row_data->[1]}{$cur_row_data->[3]}{$cur_row_data->[4]}{$cur_row_data->[5]} = { title => $cur_row_data->[0] }
315 $#{$_[0]} = $result_pos - 1;
317 'Same 1:1 descending terminating with chained 1:M:M but with collapse, HRI-direct',
321 tracks.lyrics.existing_lyric_versions.text
322 existing_single_track.cd.artist.artistid
323 existing_single_track.cd.artist.cds.year
327 existing_single_track.cd.artist.cds.cdid
329 existing_single_track.cd.artist.cds.tracks.title
330 existing_single_track.cd.artist.cds.genreid
331 tracks.lyrics.existing_lyric_versions.lyric_id
335 $schema->source('CD')->_resolve_collapse({ as => {map { $infmap->[$_] => $_ } 0 .. $#$infmap} }),
337 -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid
339 existing_single_track => {
340 -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid
344 -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid
348 -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid
352 -identifying_columns => [ 1, 6 ], # existing_single_track.cd.artist.cds.cdid
356 -identifying_columns => [ 1, 6, 8 ], # existing_single_track.cd.artist.cds.cdid, existing_single_track.cd.artist.cds.tracks.title
364 -identifying_columns => [ 1, 5 ], # existing_single_track.cd.artist.artistid, tracks.title
368 -identifying_columns => [ 1, 5, 10 ], # existing_single_track.cd.artist.artistid, tracks.title, tracks.lyrics.existing_lyric_versions.lyric_id
372 existing_lyric_versions => {
373 -identifying_columns => [ 0, 1, 5, 10 ], # tracks.lyrics.existing_lyric_versions.text, existing_single_track.cd.artist.artistid, tracks.title, tracks.lyrics.existing_lyric_versions.lyric_id
378 'Correct collapse map constructed',
382 $schema->source ('CD')->_mk_row_parser({
383 inflate_map => $infmap,
387 my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids);
389 while ($cur_row_data = (
390 ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } )
392 ( $_[1] and $_[1]->() )
395 $cur_row_ids{$_} = defined $cur_row_data->[$_] ? $cur_row_data->[$_] : "\0NULL\xFF$rows_pos\xFF$_\0"
396 for (0, 1, 5, 6, 8, 10);
398 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
399 $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{1}} and (unshift @{$_[2]}, $cur_row_data) and last;
401 $collapse_idx[0]{$cur_row_ids{1}} ||= $_[0][$result_pos++] = [{ genreid => $cur_row_data->[4], latest_cd => $cur_row_data->[7], year => $cur_row_data->[3] }];
403 $collapse_idx[0]{$cur_row_ids{1}}[1]{existing_single_track} ||= $collapse_idx[1]{$cur_row_ids{1}} = [];
404 $collapse_idx[1]{$cur_row_ids{1}}[1]{cd} ||= $collapse_idx[2]{$cur_row_ids{1}} = [];
405 $collapse_idx[2]{$cur_row_ids{1}}[1]{artist} ||= $collapse_idx[3]{$cur_row_ids{1}} = [{ artistid => $cur_row_data->[1] }];
407 (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}} )
409 push @{ $collapse_idx[3]{$cur_row_ids{1}}[1]{cds} }, (
410 $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}} = [{ cdid => $cur_row_data->[6], genreid => $cur_row_data->[9], year => $cur_row_data->[2] }]
412 defined($cur_row_data->[6]) or bless( $collapse_idx[3]{$cur_row_ids{1}}[1]{cds}, __NBC__ );
414 (! $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} )
416 push @{ $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} }, (
417 $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }]
419 defined($cur_row_data->[8]) or bless( $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks}, __NBC__ );
421 (! $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} )
423 push @{ $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} }, (
424 $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} = [{ title => $cur_row_data->[5] }]
426 defined($cur_row_data->[5]) or bless( $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks}, __NBC__ );
428 $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}}[1]{lyrics} ||= $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} = [];
429 defined($cur_row_data->[10]) or bless( $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}}[1]{lyrics}, __NBC__ );
431 (! $collapse_idx[8]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} )
433 push @{ $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}}[1]{existing_lyric_versions} }, (
434 $collapse_idx[8]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} = [{ lyric_id => $cur_row_data->[10], text => $cur_row_data->[0] }]
438 $#{$_[0]} = $result_pos - 1;
440 'Multiple has_many on multiple branches torture test',
444 $schema->source ('CD')->_mk_row_parser({
445 inflate_map => $infmap,
449 my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids);
451 while ($cur_row_data = (
452 ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } )
454 ( $_[1] and $_[1]->() )
457 $cur_row_ids{$_} = defined $cur_row_data->[$_] ? $cur_row_data->[$_] : "\0NULL\xFF$rows_pos\xFF$_\0"
458 for (0, 1, 5, 6, 8, 10);
460 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
461 $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{1}} and (unshift @{$_[2]}, $cur_row_data) and last;
463 $collapse_idx[0]{$cur_row_ids{1}} ||= $_[0][$result_pos++] = [{ genreid => $cur_row_data->[4], latest_cd => $cur_row_data->[7], year => $cur_row_data->[3] }];
465 $collapse_idx[0]{$cur_row_ids{1}}[1]{existing_single_track} ||= $collapse_idx[1]{$cur_row_ids{1}} = [];
466 $collapse_idx[1]{$cur_row_ids{1}}[1]{cd} ||= $collapse_idx[2]{$cur_row_ids{1}} = [];
467 $collapse_idx[2]{$cur_row_ids{1}}[1]{artist} ||= $collapse_idx[3]{$cur_row_ids{1}} = [{ artistid => $cur_row_data->[1] }];
469 (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}} )
471 push @{ $collapse_idx[3]{$cur_row_ids{1}}[1]{cds} }, (
472 $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}} = [{ cdid => $cur_row_data->[6], genreid => $cur_row_data->[9], year => $cur_row_data->[2] }]
474 defined($cur_row_data->[6]) or bless( $collapse_idx[3]{$cur_row_ids{1}}[1]{cds}, __NBC__ );
476 (! $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} )
478 push @{ $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} }, (
479 $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }]
481 defined($cur_row_data->[8]) or bless( $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks}, __NBC__ );
483 (! $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} )
485 push @{ $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} }, (
486 $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} = [{ title => $cur_row_data->[5] }]
488 defined($cur_row_data->[5]) or bless( $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks}, __NBC__ );
490 $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}}[1]{lyrics} ||= $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} = [];
491 defined($cur_row_data->[10]) or bless( $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}}[1]{lyrics}, __NBC__ );
493 (! $collapse_idx[8]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} )
495 push @{ $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}}[1]{existing_lyric_versions} }, (
496 $collapse_idx[8]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} = [{ lyric_id => $cur_row_data->[10], text => $cur_row_data->[0] }]
500 $#{$_[0]} = $result_pos - 1;
502 'Multiple has_many on multiple branches with branch torture test',
506 'single_track.trackid', # (0) definitive link to root from 1:1:1:1:M:M chain
507 'year', # (1) non-unique
508 'tracks.cd', # (2) \ together both uniqueness for second multirel
509 'tracks.title', # (3) / and definitive link back to root
510 'single_track.cd.artist.cds.cdid', # (4) to give uniquiness to ...tracks.title below
511 'single_track.cd.artist.cds.year', # (5) non-unique
512 'single_track.cd.artist.artistid', # (6) uniqufies entire parental chain
513 'single_track.cd.artist.cds.genreid', # (7) nullable
514 'single_track.cd.artist.cds.tracks.title',# (8) unique when combined with ...cds.cdid above
518 $schema->source('CD')->_resolve_collapse({ as => {map { $infmap->[$_] => $_ } 0 .. $#$infmap} }),
520 -identifying_columns => [],
521 -identifying_columns_variants => [
525 -identifying_columns => [ 0 ],
529 -identifying_columns => [ 0 ],
532 -identifying_columns => [ 0 ],
535 -identifying_columns => [ 0, 4 ],
538 -identifying_columns => [ 0, 4, 8 ],
546 -identifying_columns => [ 2, 3 ],
550 'Correct underdefined root collapse map constructed'
554 $schema->source ('CD')->_mk_row_parser({
555 inflate_map => $infmap,
559 my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids);
561 while ($cur_row_data = (
562 ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } )
564 ( $_[1] and $_[1]->() )
567 $cur_row_ids{$_} = defined $$cur_row_data[$_] ? $$cur_row_data[$_] : "\0NULL\xFF$rows_pos\xFF$_\0"
570 # cache expensive set of ops in a non-existent rowid slot
572 ( ( defined $cur_row_data->[0] ) && (join "\xFF", q{}, $cur_row_data->[0], q{} ))
574 ( ( defined $cur_row_data->[2] ) && (join "\xFF", q{}, $cur_row_data->[2], q{} ))
579 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
580 $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{10}} and (unshift @{$_[2]}, $cur_row_data) and last;
582 $collapse_idx[0]{$cur_row_ids{10}} ||= $_[0][$result_pos++] = [{ year => $$cur_row_data[1] }];
584 $collapse_idx[0]{$cur_row_ids{10}}[1]{single_track} ||= ($collapse_idx[1]{$cur_row_ids{0}} = [{ trackid => $cur_row_data->[0] }]);
585 defined($cur_row_data->[0]) or bless ( $collapse_idx[0]{$cur_row_ids{10}}[1]{single_track}, __NBC__ );
587 $collapse_idx[1]{$cur_row_ids{0}}[1]{cd} ||= $collapse_idx[2]{$cur_row_ids{0}} = [];
589 $collapse_idx[2]{$cur_row_ids{0}}[1]{artist} ||= ($collapse_idx[3]{$cur_row_ids{0}} = [{ artistid => $cur_row_data->[6] }]);
591 (! $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}} )
593 push @{$collapse_idx[3]{$cur_row_ids{0}}[1]{cds}}, (
594 $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}} = [{ cdid => $cur_row_data->[4], genreid => $cur_row_data->[7], year => $cur_row_data->[5] }]
596 defined($cur_row_data->[4]) or bless ( $collapse_idx[3]{$cur_row_ids{0}}[1]{cds}, __NBC__ );
598 (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} )
600 push @{$collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}[1]{tracks}}, (
601 $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }]
603 defined($cur_row_data->[8]) or bless ( $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}[1]{tracks}, __NBC__ );
605 (! $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} )
607 push @{$collapse_idx[0]{$cur_row_ids{10}}[1]{tracks}}, (
608 $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} = [{ cd => $$cur_row_data[2], title => $cur_row_data->[3] }]
610 defined($cur_row_data->[2]) or bless ( $collapse_idx[0]{$cur_row_ids{10}}[1]{tracks}, __NBC__ );
613 $#{$_[0]} = $result_pos - 1;
615 'Multiple has_many on multiple branches with underdefined root torture test',
619 $schema->source ('CD')->_mk_row_parser({
620 inflate_map => $infmap,
625 my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids);
627 while ($cur_row_data = (
628 ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } )
630 ( $_[1] and $_[1]->() )
633 $cur_row_ids{$_} = defined $$cur_row_data[$_] ? $$cur_row_data[$_] : "\0NULL\xFF$rows_pos\xFF$_\0"
636 # cache expensive set of ops in a non-existent rowid slot
638 ( ( defined $cur_row_data->[0] ) && (join "\xFF", q{}, $cur_row_data->[0], q{} ))
640 ( ( defined $cur_row_data->[2] ) && (join "\xFF", q{}, $cur_row_data->[2], q{} ))
645 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
646 $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{10}} and (unshift @{$_[2]}, $cur_row_data) and last;
648 $collapse_idx[0]{$cur_row_ids{10}} ||= $_[0][$result_pos++] = { year => $$cur_row_data[1] };
650 (! defined $cur_row_data->[0] ) ? $collapse_idx[0]{$cur_row_ids{10}}{single_track} = undef : do {
652 $collapse_idx[0]{$cur_row_ids{10}}{single_track} ||= ($collapse_idx[1]{$cur_row_ids{0}} = { trackid => $$cur_row_data[0] });
654 $collapse_idx[1]{$cur_row_ids{0}}{cd} ||= $collapse_idx[2]{$cur_row_ids{0}};
656 $collapse_idx[2]{$cur_row_ids{0}}{artist} ||= ($collapse_idx[3]{$cur_row_ids{0}} = { artistid => $$cur_row_data[6] });
658 (! defined $cur_row_data->[4] ) ? $collapse_idx[3]{$cur_row_ids{0}}{cds} = [] : do {
660 (! $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}} )
662 push @{$collapse_idx[3]{$cur_row_ids{0}}{cds}}, (
663 $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}} = { cdid => $$cur_row_data[4], genreid => $$cur_row_data[7], year => $$cur_row_data[5] }
666 (! defined $cur_row_data->[8] ) ? $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}{tracks} = [] : do {
668 (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} )
670 push @{$collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}{tracks}}, (
671 $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} = { title => $$cur_row_data[8] }
677 (! defined $cur_row_data->[2] ) ? $collapse_idx[0]{$cur_row_ids{10}}{tracks} = [] : do {
678 (! $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} )
680 push @{$collapse_idx[0]{$cur_row_ids{10}}{tracks}}, (
681 $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} = { cd => $$cur_row_data[2], title => $$cur_row_data[3] }
686 $#{$_[0]} = $result_pos - 1;
688 'Multiple has_many on multiple branches with underdefined root, HRI-direct torture test',
695 $deparser ||= B::Deparse->new;
696 local $Test::Builder::Level = $Test::Builder::Level + 1;
698 my ($got, $expect) = @_;
700 $expect =~ s/__NBC__/B::perlstring($DBIx::Class::ResultSource::RowParser::Util::null_branch_class)/ge;
702 $expect = " { use strict; use warnings FATAL => 'all';\n$expect\n }";
704 my @normalized = map {
705 my $cref = eval "sub { $_ }" or do {
706 fail "Coderef does not compile!\n\n$@\n\n$_";
709 $deparser->coderef2text($cref);
712 &is (@normalized, $_[2]||() ) or do {
713 eval { require Test::Differences }
714 ? &Test::Differences::eq_or_diff( @normalized, $_[2]||() )
715 : note ("Original sources:\n\n$got\n\n$expect\n")