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,
39 'Simple 1:1 descending non-collapsing parser',
43 single_track.cd.artist.cds.tracks.title
44 single_track.cd.artist.artistid
46 single_track.cd.artist.cds.cdid
51 $schema->source ('CD')->_mk_row_parser({
52 inflate_map => $infmap,
55 { artist => $_->[5], title => $_->[4], year => $_->[2] },
61 { artistid => $_->[1] },
72 '1:1 descending non-collapsing parser terminating with chained 1:M:M',
76 $schema->source ('CD')->_mk_row_parser({
77 prune_null_branches => 1,
78 inflate_map => $infmap,
81 { artist => $_->[5], title => $_->[4], year => $_->[2] },
83 ( (! defined $_->[0] ) && (! defined $_->[1]) && (! defined $_->[3] ) )
84 ? ( single_track => [] )
92 { artistid => $_->[1] },
94 ( (! defined $_->[0] ) && ( ! defined $_->[3] ) )
101 : ( tracks => [{ title => $_->[0] }] )
112 '1:1 descending non-collapsing null-pruning parser terminating with chained 1:M:M',
116 $schema->source ('CD')->_mk_row_parser({
117 prune_null_branches => 1,
119 inflate_map => $infmap,
122 artist => $_->[5], title => $_->[4], year => $_->[2],
124 ( (! defined $_->[0] ) && (! defined $_->[1]) && (! defined $_->[3] ) )
125 ? ( single_track => undef )
126 : ( single_track => {
131 ( (! defined $_->[0] ) && ( ! defined $_->[3] ) )
135 ( ! defined $_->[0] )
136 ? ( tracks => undef )
137 : ( tracks => { title => $_->[0] } )
145 '1:1 descending non-collapsing null-pruning HRI-direct parser terminating with chained 1:M:M',
151 ($schema->source('CD')->_resolve_collapse({ as => {map { $infmap->[$_] => $_ } 0 .. $#$infmap} })),
153 -identifying_columns => [ 4, 5 ],
156 -identifying_columns => [ 1, 4, 5 ],
161 -identifying_columns => [ 1, 4, 5 ],
165 -identifying_columns => [ 1, 4, 5 ],
169 -identifying_columns => [ 1, 3, 4, 5 ],
173 -identifying_columns => [ 0, 1, 3, 4, 5 ],
181 'Correct collapse map for 1:1 descending chain terminating with chained 1:M:M'
185 $schema->source ('CD')->_mk_row_parser({
186 inflate_map => $infmap,
189 ' my($rows_pos, $result_pos, $cur_row_data, %cur_row_ids, @collapse_idx, $is_new_res) = (0, 0);
191 while ($cur_row_data = (
192 ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } )
194 ( $_[1] and $_[1]->() )
197 $cur_row_ids{$_} = defined $cur_row_data->[$_] ? $cur_row_data->[$_] : "\0NULL\xFF$rows_pos\xFF$_\0"
200 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
201 $_[1] and $result_pos and unshift(@{$_[2]}, $cur_row_data) and last
202 if ( $is_new_res = ! $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}} );
204 # the rowdata itself for root node
205 $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] }];
207 # prefetch data of single_track (placed in root)
208 $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}};
210 # prefetch data of cd (placed in single_track)
211 $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}};
213 # prefetch data of artist ( placed in single_track->cd)
214 $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] }];
216 # prefetch data of cds (if available)
217 (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} )
219 push @{$collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{cds}}, (
220 $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} = [{ cdid => $cur_row_data->[3] }]
223 # prefetch data of tracks (if available)
224 (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} )
226 push @{$collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{tracks}}, (
227 $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] }]
230 $_[0][$result_pos++] = $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}}
233 splice @{$_[0]}, $result_pos;
235 'Same 1:1 descending terminating with chained 1:M:M but with collapse',
239 $schema->source ('CD')->_mk_row_parser({
240 inflate_map => $infmap,
242 prune_null_branches => 1,
245 ' my($rows_pos, $result_pos, $cur_row_data, %cur_row_ids, @collapse_idx, $is_new_res) = (0, 0);
247 while ($cur_row_data = (
248 ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } )
250 ( $_[1] and $_[1]->() )
253 $cur_row_ids{$_} = defined $cur_row_data->[$_] ? $cur_row_data->[$_] : "\0NULL\xFF$rows_pos\xFF$_\0"
256 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
257 $_[1] and $result_pos and unshift(@{$_[2]}, $cur_row_data) and last
258 if ( $is_new_res = ! $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}} );
260 # the rowdata itself for root node
261 $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] };
263 # prefetch data of single_track (placed in root)
264 $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}}{single_track} ||= $collapse_idx[1]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}
265 if defined $cur_row_data->[1];
266 $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}}{single_track} ||= undef;
268 # prefetch data of cd (placed in single_track)
269 $collapse_idx[1]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}{cd} ||= $collapse_idx[2]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}};
271 # prefetch data of artist ( placed in single_track->cd)
272 $collapse_idx[2]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}{artist} ||= $collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}} ||= { artistid => $cur_row_data->[1] };
274 # prefetch data of cds (if available)
275 ( defined $cur_row_data->[3] )
277 (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} )
279 push @{$collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}{cds}}, (
280 $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} = { cdid => $cur_row_data->[3] }
282 $collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}{cds} ||= [];
284 # prefetch data of tracks (if available)
285 ( defined $cur_row_data->[0] )
287 (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} )
289 push @{$collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}}{tracks}}, (
290 $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] }
292 $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}}{tracks} ||= [];
294 $_[0][$result_pos++] = $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}}
297 splice @{$_[0]}, $result_pos;
299 'Same 1:1 descending terminating with chained 1:M:M but with collapse, pruning, hri-style',
303 tracks.lyrics.existing_lyric_versions.text
304 existing_single_track.cd.artist.artistid
305 existing_single_track.cd.artist.cds.year
309 existing_single_track.cd.artist.cds.cdid
311 existing_single_track.cd.artist.cds.tracks.title
312 existing_single_track.cd.artist.cds.genreid
313 tracks.lyrics.existing_lyric_versions.lyric_id
317 $schema->source('CD')->_resolve_collapse({ as => {map { $infmap->[$_] => $_ } 0 .. $#$infmap} }),
319 -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid
321 existing_single_track => {
322 -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid
326 -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid
330 -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid
334 -identifying_columns => [ 1, 6 ], # existing_single_track.cd.artist.cds.cdid
338 -identifying_columns => [ 1, 6, 8 ], # existing_single_track.cd.artist.cds.cdid, existing_single_track.cd.artist.cds.tracks.title
346 -identifying_columns => [ 1, 5 ], # existing_single_track.cd.artist.artistid, tracks.title
350 -identifying_columns => [ 1, 5, 10 ], # existing_single_track.cd.artist.artistid, tracks.title, tracks.lyrics.existing_lyric_versions.lyric_id
354 existing_lyric_versions => {
355 -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
360 'Correct collapse map constructed',
364 $schema->source ('CD')->_mk_row_parser({
365 inflate_map => $infmap,
368 ' my ($rows_pos, $result_pos, $cur_row_data, %cur_row_ids, @collapse_idx, $is_new_res) = (0,0);
370 while ($cur_row_data = (
371 ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } )
373 ( $_[1] and $_[1]->() )
376 $cur_row_ids{$_} = defined $cur_row_data->[$_] ? $cur_row_data->[$_] : "\0NULL\xFF$rows_pos\xFF$_\0"
377 for (0, 1, 5, 6, 8, 10);
379 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
380 $_[1] and $result_pos and unshift(@{$_[2]}, $cur_row_data) and last
381 if ( $is_new_res = ! $collapse_idx[0]{$cur_row_ids{1}} );
383 $collapse_idx[0]{$cur_row_ids{1}} ||= [{ genreid => $cur_row_data->[4], latest_cd => $cur_row_data->[7], year => $cur_row_data->[3] }];
385 $collapse_idx[0]{$cur_row_ids{1}}[1]{existing_single_track} ||= $collapse_idx[1]{$cur_row_ids{1}};
386 $collapse_idx[1]{$cur_row_ids{1}}[1]{cd} ||= $collapse_idx[2]{$cur_row_ids{1}};
387 $collapse_idx[2]{$cur_row_ids{1}}[1]{artist} ||= $collapse_idx[3]{$cur_row_ids{1}} ||= [{ artistid => $cur_row_data->[1] }];
389 (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}} )
391 push @{ $collapse_idx[3]{$cur_row_ids{1}}[1]{cds} }, (
392 $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] }]
395 (! $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} )
397 push @{ $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} }, (
398 $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }]
401 (! $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} )
403 push @{ $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} }, (
404 $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} = [{ title => $cur_row_data->[5] }]
407 $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}};
409 (! $collapse_idx[8]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} )
411 push @{ $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}}[1]{existing_lyric_versions} }, (
412 $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] }]
415 $_[0][$result_pos++] = $collapse_idx[0]{$cur_row_ids{1}}
419 splice @{$_[0]}, $result_pos;
421 'Multiple has_many on multiple branches torture test',
425 $schema->source ('CD')->_mk_row_parser({
426 inflate_map => $infmap,
428 prune_null_branches => 1,
430 ' my ($rows_pos, $result_pos, $cur_row_data, %cur_row_ids, @collapse_idx, $is_new_res) = (0,0);
432 while ($cur_row_data = (
433 ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } )
435 ( $_[1] and $_[1]->() )
438 $cur_row_ids{$_} = defined $cur_row_data->[$_] ? $cur_row_data->[$_] : "\0NULL\xFF$rows_pos\xFF$_\0"
439 for (0, 1, 5, 6, 8, 10);
441 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
442 $_[1] and $result_pos and unshift(@{$_[2]}, $cur_row_data) and last
443 if ( $is_new_res = ! $collapse_idx[0]{$cur_row_ids{1}} );
445 $collapse_idx[0]{$cur_row_ids{1}} ||= [{ genreid => $cur_row_data->[4], latest_cd => $cur_row_data->[7], year => $cur_row_data->[3] }];
447 $collapse_idx[0]{$cur_row_ids{1}}[1]{existing_single_track} ||= $collapse_idx[1]{$cur_row_ids{1}};
448 $collapse_idx[1]{$cur_row_ids{1}}[1]{cd} ||= $collapse_idx[2]{$cur_row_ids{1}};
449 $collapse_idx[2]{$cur_row_ids{1}}[1]{artist} ||= $collapse_idx[3]{$cur_row_ids{1}} ||= [{ artistid => $cur_row_data->[1] }];
451 (defined $cur_row_data->[6])
453 (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}} )
455 push @{ $collapse_idx[3]{$cur_row_ids{1}}[1]{cds} }, (
456 $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] }]
458 $collapse_idx[3]{$cur_row_ids{1}}[1]{cds} ||= [];
460 (defined $cur_row_data->[8])
462 (! $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} )
464 push @{ $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} }, (
465 $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }]
467 $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} ||= [];
469 (defined $cur_row_data->[5])
471 (! $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} )
473 push @{ $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} }, (
474 $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} = [{ title => $cur_row_data->[5] }]
476 $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} ||= [];
478 (defined $cur_row_data->[10])
480 $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}};
481 $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}}[1]{lyrics} ||= [];
483 (defined $cur_row_data->[0])
485 (! $collapse_idx[8]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} )
487 push @{ $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}}[1]{existing_lyric_versions} }, (
488 $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] }]
490 $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}}[1]{existing_lyric_versions} ||= [];
492 $_[0][$result_pos++] = $collapse_idx[0]{$cur_row_ids{1}}
496 splice @{$_[0]}, $result_pos;
498 'Multiple has_many on multiple branches with branch pruning torture test',
502 'single_track.trackid', # (0) definitive link to root from 1:1:1:1:M:M chain
503 'year', # (1) non-unique
504 'tracks.cd', # (2) \ together both uniqueness for second multirel
505 'tracks.title', # (3) / and definitive link back to root
506 'single_track.cd.artist.cds.cdid', # (4) to give uniquiness to ...tracks.title below
507 'single_track.cd.artist.cds.year', # (5) non-unique
508 'single_track.cd.artist.artistid', # (6) uniqufies entire parental chain
509 'single_track.cd.artist.cds.genreid', # (7) nullable
510 'single_track.cd.artist.cds.tracks.title',# (8) unique when combined with ...cds.cdid above
514 $schema->source('CD')->_resolve_collapse({ as => {map { $infmap->[$_] => $_ } 0 .. $#$infmap} }),
516 -identifying_columns => [],
517 -identifying_columns_variants => [
521 -identifying_columns => [ 0 ],
525 -identifying_columns => [ 0 ],
528 -identifying_columns => [ 0 ],
531 -identifying_columns => [ 0, 4 ],
534 -identifying_columns => [ 0, 4, 8 ],
542 -identifying_columns => [ 2, 3 ],
546 'Correct underdefined root collapse map constructed'
550 $schema->source ('CD')->_mk_row_parser({
551 inflate_map => $infmap,
554 ' my($rows_pos, $result_pos, $cur_row_data, %cur_row_ids, @collapse_idx, $is_new_res) = (0, 0);
556 while ($cur_row_data = (
557 ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } )
559 ( $_[1] and $_[1]->() )
562 $cur_row_ids{$_} = defined $$cur_row_data[$_] ? $$cur_row_data[$_] : "\0NULL\xFF$rows_pos\xFF$_\0"
565 # cache expensive set of ops in a non-existent rowid slot
567 ( ( defined $cur_row_data->[0] ) && (join "\xFF", q{}, $cur_row_data->[0], q{} ))
569 ( ( defined $cur_row_data->[2] ) && (join "\xFF", q{}, $cur_row_data->[2], q{} ))
574 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
575 $_[1] and $result_pos and unshift(@{$_[2]}, $cur_row_data) and last
576 if ( $is_new_res = ! $collapse_idx[0]{$cur_row_ids{10}} );
578 $collapse_idx[0]{$cur_row_ids{10}} ||= [{ year => $$cur_row_data[1] }];
580 $collapse_idx[0]{$cur_row_ids{10}}[1]{single_track} ||= ($collapse_idx[1]{$cur_row_ids{0}} ||= [{ trackid => $$cur_row_data[0] }]);
582 $collapse_idx[1]{$cur_row_ids{0}}[1]{cd} ||= $collapse_idx[2]{$cur_row_ids{0}};
584 $collapse_idx[2]{$cur_row_ids{0}}[1]{artist} ||= ($collapse_idx[3]{$cur_row_ids{0}} ||= [{ artistid => $$cur_row_data[6] }]);
586 (! $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}} )
588 push @{$collapse_idx[3]{$cur_row_ids{0}}[1]{cds}}, (
589 $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] }]
592 (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} )
594 push @{$collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}[1]{tracks}}, (
595 $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} = [{ title => $$cur_row_data[8] }]
598 (! $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} )
600 push @{$collapse_idx[0]{$cur_row_ids{10}}[1]{tracks}}, (
601 $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} = [{ cd => $$cur_row_data[2], title => $$cur_row_data[3] }]
604 $_[0][$result_pos++] = $collapse_idx[0]{$cur_row_ids{10}}
608 splice @{$_[0]}, $result_pos;
610 'Multiple has_many on multiple branches with underdefined root torture test',
614 $schema->source ('CD')->_mk_row_parser({
615 inflate_map => $infmap,
617 prune_null_branches => 1,
620 ' my($rows_pos, $result_pos, $cur_row_data, %cur_row_ids, @collapse_idx, $is_new_res) = (0, 0);
622 while ($cur_row_data = (
623 ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } )
625 ( $_[1] and $_[1]->() )
628 $cur_row_ids{$_} = defined $$cur_row_data[$_] ? $$cur_row_data[$_] : "\0NULL\xFF$rows_pos\xFF$_\0"
631 # cache expensive set of ops in a non-existent rowid slot
633 ( ( defined $cur_row_data->[0] ) && (join "\xFF", q{}, $cur_row_data->[0], q{} ))
635 ( ( defined $cur_row_data->[2] ) && (join "\xFF", q{}, $cur_row_data->[2], q{} ))
640 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
641 $_[1] and $result_pos and unshift(@{$_[2]}, $cur_row_data) and last
642 if ( $is_new_res = ! $collapse_idx[0]{$cur_row_ids{10}} );
644 $collapse_idx[0]{$cur_row_ids{10}} ||= { year => $$cur_row_data[1] };
646 (defined $cur_row_data->[0])
648 $collapse_idx[0]{$cur_row_ids{10}}{single_track} ||= ($collapse_idx[1]{$cur_row_ids{0}} ||= { trackid => $$cur_row_data[0] });
649 $collapse_idx[0]{$cur_row_ids{10}}{single_track} ||= undef;
651 $collapse_idx[1]{$cur_row_ids{0}}{cd} ||= $collapse_idx[2]{$cur_row_ids{0}};
653 $collapse_idx[2]{$cur_row_ids{0}}{artist} ||= ($collapse_idx[3]{$cur_row_ids{0}} ||= { artistid => $$cur_row_data[6] });
655 (defined $cur_row_data->[4])
657 (! $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}} )
659 push @{$collapse_idx[3]{$cur_row_ids{0}}{cds}}, (
660 $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] }
662 $collapse_idx[3]{$cur_row_ids{0}}{cds} ||= [];
664 (defined $cur_row_data->[8])
666 (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} )
668 push @{$collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}{tracks}}, (
669 $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} = { title => $$cur_row_data[8] }
671 $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}{tracks} ||= [];
673 (defined $cur_row_data->[2])
675 (! $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} )
677 push @{$collapse_idx[0]{$cur_row_ids{10}}{tracks}}, (
678 $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} = { cd => $$cur_row_data[2], title => $$cur_row_data[3] }
680 $collapse_idx[0]{$cur_row_ids{10}}{tracks} ||= [];
682 $_[0][$result_pos++] = $collapse_idx[0]{$cur_row_ids{10}}
686 splice @{$_[0]}, $result_pos;
688 'Multiple has_many on multiple branches with underdefined root, hri style with branch pruning torture test',
695 $deparser ||= B::Deparse->new;
696 local $Test::Builder::Level = $Test::Builder::Level + 1;
698 my ($got, $expect) = map {
699 my $cref = eval "sub { $_ }" or do {
700 fail "Coderef does not compile!\n\n$@\n\n$_";
703 $deparser->coderef2text($cref);
706 #use Test::Differences;
707 #eq_or_diff($got, $expect);
709 is ($got, $expect, $_[2]||() )
710 or note ("Originals source:\n\n$_[0]\n\n$_[1]\n");