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,
213 ' my($rows_pos, $result_pos, $cur_row_data, %cur_row_ids, @collapse_idx, $is_new_res) = (0, 0);
215 while ($cur_row_data = (
216 ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } )
218 ( $_[1] and $_[1]->() )
221 $cur_row_ids{$_} = defined $cur_row_data->[$_] ? $cur_row_data->[$_] : "\0NULL\xFF$rows_pos\xFF$_\0"
224 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
225 $_[1] and $result_pos and unshift(@{$_[2]}, $cur_row_data) and last
226 if ( $is_new_res = ! $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}} );
228 # the rowdata itself for root node
229 $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}} ||= [{ 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__ );
257 $_[0][$result_pos++] = $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}}
260 splice @{$_[0]}, $result_pos;
262 'Same 1:1 descending terminating with chained 1:M:M but with collapse',
266 $schema->source ('CD')->_mk_row_parser({
267 inflate_map => $infmap,
271 ' my($rows_pos, $result_pos, $cur_row_data, @collapse_idx, $is_new_res) = (0, 0);
273 while ($cur_row_data = (
274 ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } )
276 ( $_[1] and $_[1]->() )
279 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
280 $_[1] and $result_pos and unshift(@{$_[2]}, $cur_row_data) and last
281 if ( $is_new_res = ! $collapse_idx[0]{$cur_row_data->[4]}{$cur_row_data->[5]} );
283 # the rowdata itself for root node
284 $collapse_idx[0]{$cur_row_data->[4]}{$cur_row_data->[5]} ||= { artist => $cur_row_data->[5], title => $cur_row_data->[4], year => $cur_row_data->[2] };
286 # prefetch data of single_track (placed in root)
287 (! defined($cur_row_data->[1]) ) ? $collapse_idx[0]{$cur_row_data->[4]}{$cur_row_data->[5]}{single_track} = undef : do {
288 $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]};
290 # prefetch data of cd (placed in single_track)
291 $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]};
293 # prefetch data of artist ( placed in single_track->cd)
294 $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] };
296 # prefetch data of cds (if available)
297 (! defined $cur_row_data->[3] ) ? $collapse_idx[3]{$cur_row_data->[1]}{$cur_row_data->[4]}{$cur_row_data->[5]}{cds} = [] : do {
299 (! $collapse_idx[4]{$cur_row_data->[1]}{$cur_row_data->[3]}{$cur_row_data->[4]}{$cur_row_data->[5]} )
301 push @{$collapse_idx[3]{$cur_row_data->[1]}{$cur_row_data->[4]}{$cur_row_data->[5]}{cds}}, (
302 $collapse_idx[4]{$cur_row_data->[1]}{$cur_row_data->[3]}{$cur_row_data->[4]}{$cur_row_data->[5]} = { cdid => $cur_row_data->[3] }
305 # prefetch data of tracks (if available)
306 ( ! 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 {
308 (! $collapse_idx[5]{$cur_row_data->[0]}{$cur_row_data->[1]}{$cur_row_data->[3]}{$cur_row_data->[4]}{$cur_row_data->[5]} )
310 push @{$collapse_idx[4]{$cur_row_data->[1]}{$cur_row_data->[3]}{$cur_row_data->[4]}{$cur_row_data->[5]}{tracks}}, (
311 $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] }
317 $_[0][$result_pos++] = $collapse_idx[0]{$cur_row_data->[4]}{$cur_row_data->[5]}
320 splice @{$_[0]}, $result_pos;
322 'Same 1:1 descending terminating with chained 1:M:M but with collapse, HRI-direct',
326 tracks.lyrics.existing_lyric_versions.text
327 existing_single_track.cd.artist.artistid
328 existing_single_track.cd.artist.cds.year
332 existing_single_track.cd.artist.cds.cdid
334 existing_single_track.cd.artist.cds.tracks.title
335 existing_single_track.cd.artist.cds.genreid
336 tracks.lyrics.existing_lyric_versions.lyric_id
340 $schema->source('CD')->_resolve_collapse({ as => {map { $infmap->[$_] => $_ } 0 .. $#$infmap} }),
342 -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid
344 existing_single_track => {
345 -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid
349 -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid
353 -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid
357 -identifying_columns => [ 1, 6 ], # existing_single_track.cd.artist.cds.cdid
361 -identifying_columns => [ 1, 6, 8 ], # existing_single_track.cd.artist.cds.cdid, existing_single_track.cd.artist.cds.tracks.title
369 -identifying_columns => [ 1, 5 ], # existing_single_track.cd.artist.artistid, tracks.title
373 -identifying_columns => [ 1, 5, 10 ], # existing_single_track.cd.artist.artistid, tracks.title, tracks.lyrics.existing_lyric_versions.lyric_id
377 existing_lyric_versions => {
378 -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
383 'Correct collapse map constructed',
387 $schema->source ('CD')->_mk_row_parser({
388 inflate_map => $infmap,
391 ' my ($rows_pos, $result_pos, $cur_row_data, %cur_row_ids, @collapse_idx, $is_new_res) = (0,0);
393 while ($cur_row_data = (
394 ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } )
396 ( $_[1] and $_[1]->() )
399 $cur_row_ids{$_} = defined $cur_row_data->[$_] ? $cur_row_data->[$_] : "\0NULL\xFF$rows_pos\xFF$_\0"
400 for (0, 1, 5, 6, 8, 10);
402 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
403 $_[1] and $result_pos and unshift(@{$_[2]}, $cur_row_data) and last
404 if ( $is_new_res = ! $collapse_idx[0]{$cur_row_ids{1}} );
406 $collapse_idx[0]{$cur_row_ids{1}} ||= [{ genreid => $cur_row_data->[4], latest_cd => $cur_row_data->[7], year => $cur_row_data->[3] }];
408 $collapse_idx[0]{$cur_row_ids{1}}[1]{existing_single_track} ||= $collapse_idx[1]{$cur_row_ids{1}} ||= [];
409 $collapse_idx[1]{$cur_row_ids{1}}[1]{cd} ||= $collapse_idx[2]{$cur_row_ids{1}} ||= [];
410 $collapse_idx[2]{$cur_row_ids{1}}[1]{artist} ||= $collapse_idx[3]{$cur_row_ids{1}} ||= [{ artistid => $cur_row_data->[1] }];
412 (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}} )
414 push @{ $collapse_idx[3]{$cur_row_ids{1}}[1]{cds} }, (
415 $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] }]
417 defined($cur_row_data->[6]) or bless( $collapse_idx[3]{$cur_row_ids{1}}[1]{cds}, __NBC__ );
419 (! $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} )
421 push @{ $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} }, (
422 $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }]
424 defined($cur_row_data->[8]) or bless( $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks}, __NBC__ );
426 (! $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} )
428 push @{ $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} }, (
429 $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} = [{ title => $cur_row_data->[5] }]
431 defined($cur_row_data->[5]) or bless( $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks}, __NBC__ );
433 $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}} ||= [];
434 defined($cur_row_data->[10]) or bless( $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}}[1]{lyrics}, __NBC__ );
436 (! $collapse_idx[8]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} )
438 push @{ $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}}[1]{existing_lyric_versions} }, (
439 $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] }]
442 $_[0][$result_pos++] = $collapse_idx[0]{$cur_row_ids{1}}
446 splice @{$_[0]}, $result_pos;
448 'Multiple has_many on multiple branches torture test',
452 $schema->source ('CD')->_mk_row_parser({
453 inflate_map => $infmap,
456 ' my ($rows_pos, $result_pos, $cur_row_data, %cur_row_ids, @collapse_idx, $is_new_res) = (0,0);
458 while ($cur_row_data = (
459 ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } )
461 ( $_[1] and $_[1]->() )
464 $cur_row_ids{$_} = defined $cur_row_data->[$_] ? $cur_row_data->[$_] : "\0NULL\xFF$rows_pos\xFF$_\0"
465 for (0, 1, 5, 6, 8, 10);
467 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
468 $_[1] and $result_pos and unshift(@{$_[2]}, $cur_row_data) and last
469 if ( $is_new_res = ! $collapse_idx[0]{$cur_row_ids{1}} );
471 $collapse_idx[0]{$cur_row_ids{1}} ||= [{ genreid => $cur_row_data->[4], latest_cd => $cur_row_data->[7], year => $cur_row_data->[3] }];
473 $collapse_idx[0]{$cur_row_ids{1}}[1]{existing_single_track} ||= $collapse_idx[1]{$cur_row_ids{1}} ||= [];
474 $collapse_idx[1]{$cur_row_ids{1}}[1]{cd} ||= $collapse_idx[2]{$cur_row_ids{1}} ||= [];
475 $collapse_idx[2]{$cur_row_ids{1}}[1]{artist} ||= $collapse_idx[3]{$cur_row_ids{1}} ||= [{ artistid => $cur_row_data->[1] }];
477 (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}} )
479 push @{ $collapse_idx[3]{$cur_row_ids{1}}[1]{cds} }, (
480 $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] }]
482 defined($cur_row_data->[6]) or bless( $collapse_idx[3]{$cur_row_ids{1}}[1]{cds}, __NBC__ );
484 (! $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} )
486 push @{ $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} }, (
487 $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }]
489 defined($cur_row_data->[8]) or bless( $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks}, __NBC__ );
491 (! $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} )
493 push @{ $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} }, (
494 $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} = [{ title => $cur_row_data->[5] }]
496 defined($cur_row_data->[5]) or bless( $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks}, __NBC__ );
498 $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}} ||= [];
499 defined($cur_row_data->[10]) or bless( $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}}[1]{lyrics}, __NBC__ );
501 (! $collapse_idx[8]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} )
503 push @{ $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}}[1]{existing_lyric_versions} }, (
504 $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] }]
507 $_[0][$result_pos++] = $collapse_idx[0]{$cur_row_ids{1}}
511 splice @{$_[0]}, $result_pos;
513 'Multiple has_many on multiple branches with branch torture test',
517 'single_track.trackid', # (0) definitive link to root from 1:1:1:1:M:M chain
518 'year', # (1) non-unique
519 'tracks.cd', # (2) \ together both uniqueness for second multirel
520 'tracks.title', # (3) / and definitive link back to root
521 'single_track.cd.artist.cds.cdid', # (4) to give uniquiness to ...tracks.title below
522 'single_track.cd.artist.cds.year', # (5) non-unique
523 'single_track.cd.artist.artistid', # (6) uniqufies entire parental chain
524 'single_track.cd.artist.cds.genreid', # (7) nullable
525 'single_track.cd.artist.cds.tracks.title',# (8) unique when combined with ...cds.cdid above
529 $schema->source('CD')->_resolve_collapse({ as => {map { $infmap->[$_] => $_ } 0 .. $#$infmap} }),
531 -identifying_columns => [],
532 -identifying_columns_variants => [
536 -identifying_columns => [ 0 ],
540 -identifying_columns => [ 0 ],
543 -identifying_columns => [ 0 ],
546 -identifying_columns => [ 0, 4 ],
549 -identifying_columns => [ 0, 4, 8 ],
557 -identifying_columns => [ 2, 3 ],
561 'Correct underdefined root collapse map constructed'
565 $schema->source ('CD')->_mk_row_parser({
566 inflate_map => $infmap,
569 ' my($rows_pos, $result_pos, $cur_row_data, %cur_row_ids, @collapse_idx, $is_new_res) = (0, 0);
571 while ($cur_row_data = (
572 ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } )
574 ( $_[1] and $_[1]->() )
577 $cur_row_ids{$_} = defined $$cur_row_data[$_] ? $$cur_row_data[$_] : "\0NULL\xFF$rows_pos\xFF$_\0"
580 # cache expensive set of ops in a non-existent rowid slot
582 ( ( defined $cur_row_data->[0] ) && (join "\xFF", q{}, $cur_row_data->[0], q{} ))
584 ( ( defined $cur_row_data->[2] ) && (join "\xFF", q{}, $cur_row_data->[2], q{} ))
589 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
590 $_[1] and $result_pos and unshift(@{$_[2]}, $cur_row_data) and last
591 if ( $is_new_res = ! $collapse_idx[0]{$cur_row_ids{10}} );
593 $collapse_idx[0]{$cur_row_ids{10}} ||= [{ year => $$cur_row_data[1] }];
595 $collapse_idx[0]{$cur_row_ids{10}}[1]{single_track} ||= ($collapse_idx[1]{$cur_row_ids{0}} ||= [{ trackid => $cur_row_data->[0] }]);
596 defined($cur_row_data->[0]) or bless ( $collapse_idx[0]{$cur_row_ids{10}}[1]{single_track}, __NBC__ );
598 $collapse_idx[1]{$cur_row_ids{0}}[1]{cd} ||= $collapse_idx[2]{$cur_row_ids{0}} ||= [];
600 $collapse_idx[2]{$cur_row_ids{0}}[1]{artist} ||= ($collapse_idx[3]{$cur_row_ids{0}} ||= [{ artistid => $cur_row_data->[6] }]);
602 (! $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}} )
604 push @{$collapse_idx[3]{$cur_row_ids{0}}[1]{cds}}, (
605 $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] }]
607 defined($cur_row_data->[4]) or bless ( $collapse_idx[3]{$cur_row_ids{0}}[1]{cds}, __NBC__ );
609 (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} )
611 push @{$collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}[1]{tracks}}, (
612 $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }]
614 defined($cur_row_data->[8]) or bless ( $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}[1]{tracks}, __NBC__ );
616 (! $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} )
618 push @{$collapse_idx[0]{$cur_row_ids{10}}[1]{tracks}}, (
619 $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} = [{ cd => $$cur_row_data[2], title => $cur_row_data->[3] }]
621 defined($cur_row_data->[2]) or bless ( $collapse_idx[0]{$cur_row_ids{10}}[1]{tracks}, __NBC__ );
623 $_[0][$result_pos++] = $collapse_idx[0]{$cur_row_ids{10}}
627 splice @{$_[0]}, $result_pos;
629 'Multiple has_many on multiple branches with underdefined root torture test',
633 $schema->source ('CD')->_mk_row_parser({
634 inflate_map => $infmap,
638 ' my($rows_pos, $result_pos, $cur_row_data, @collapse_idx, $is_new_res) = (0, 0);
640 while ($cur_row_data = (
641 ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } )
643 ( $_[1] and $_[1]->() )
646 # cache expensive set of ops in a non-existent rowid slot
647 $cur_row_data->[10] = (
648 ( ( defined $cur_row_data->[0] ) && (join "\xFF", q{}, $cur_row_data->[0], q{} ))
650 ( ( defined $cur_row_data->[2] ) && (join "\xFF", q{}, $cur_row_data->[2], q{} ))
655 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
656 $_[1] and $result_pos and unshift(@{$_[2]}, $cur_row_data) and last
657 if ( $is_new_res = ! $collapse_idx[0]{$cur_row_data->[10]} );
659 $collapse_idx[0]{$cur_row_data->[10]} ||= { year => $$cur_row_data[1] };
661 (! defined $cur_row_data->[0] ) ? $collapse_idx[0]{$cur_row_data->[10]}{single_track} = undef : do {
663 $collapse_idx[0]{$cur_row_data->[10]}{single_track} ||= ($collapse_idx[1]{$cur_row_data->[0]} ||= { trackid => $$cur_row_data[0] });
665 $collapse_idx[1]{$cur_row_data->[0]}{cd} ||= $collapse_idx[2]{$cur_row_data->[0]};
667 $collapse_idx[2]{$cur_row_data->[0]}{artist} ||= ($collapse_idx[3]{$cur_row_data->[0]} ||= { artistid => $$cur_row_data[6] });
669 (! defined $cur_row_data->[4] ) ? $collapse_idx[3]{$cur_row_data->[0]}{cds} = [] : do {
671 (! $collapse_idx[4]{$cur_row_data->[0]}{$cur_row_data->[4]} )
673 push @{$collapse_idx[3]{$cur_row_data->[0]}{cds}}, (
674 $collapse_idx[4]{$cur_row_data->[0]}{$cur_row_data->[4]} = { cdid => $$cur_row_data[4], genreid => $$cur_row_data[7], year => $$cur_row_data[5] }
677 (! defined $cur_row_data->[8] ) ? $collapse_idx[4]{$cur_row_data->[0]}{$cur_row_data->[4]}{tracks} = [] : do {
679 (! $collapse_idx[5]{$cur_row_data->[0]}{$cur_row_data->[4]}{$cur_row_data->[8]} )
681 push @{$collapse_idx[4]{$cur_row_data->[0]}{$cur_row_data->[4]}{tracks}}, (
682 $collapse_idx[5]{$cur_row_data->[0]}{$cur_row_data->[4]}{$cur_row_data->[8]} = { title => $$cur_row_data[8] }
688 (! defined $cur_row_data->[2] ) ? $collapse_idx[0]{$cur_row_data->[10]}{tracks} = [] : do {
689 (! $collapse_idx[6]{$cur_row_data->[2]}{$cur_row_data->[3]} )
691 push @{$collapse_idx[0]{$cur_row_data->[10]}{tracks}}, (
692 $collapse_idx[6]{$cur_row_data->[2]}{$cur_row_data->[3]} = { cd => $$cur_row_data[2], title => $$cur_row_data[3] }
696 $_[0][$result_pos++] = $collapse_idx[0]{$cur_row_data->[10]}
700 splice @{$_[0]}, $result_pos;
702 'Multiple has_many on multiple branches with underdefined root, HRI-direct torture test',
709 $deparser ||= B::Deparse->new;
710 local $Test::Builder::Level = $Test::Builder::Level + 1;
712 my ($got, $expect) = @_;
714 $expect =~ s/__NBC__/B::perlstring($DBIx::Class::ResultSource::RowParser::Util::null_branch_class)/ge;
716 $expect = " { use strict; use warnings FATAL => 'all';\n$expect\n }";
718 my @normalized = map {
719 my $cref = eval "sub { $_ }" or do {
720 fail "Coderef does not compile!\n\n$@\n\n$_";
723 $deparser->coderef2text($cref);
726 &is (@normalized, $_[2]||() ) or do {
727 eval { require Test::Differences }
728 ? &Test::Differences::eq_or_diff( @normalized, $_[2]||() )
729 : note ("Original sources:\n\n$got\n\n$expect\n")