X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=t%2Fresultset%2Frowparser_internals.t;h=5818248b1e90e16a6c103f4432341be08ac2ebf4;hb=908c46a247ef2d3f471f6d24ec16e90080354593;hp=c7d8ac8e21fb01ff0ea0c09f31e68e8da7a8453c;hpb=aa1d8a8751baf1e4c06b43f38ff9e02cdea51e6a;p=dbsrgits%2FDBIx-Class.git diff --git a/t/resultset/rowparser_internals.t b/t/resultset/rowparser_internals.t index c7d8ac8..5818248 100644 --- a/t/resultset/rowparser_internals.t +++ b/t/resultset/rowparser_internals.t @@ -5,6 +5,7 @@ use Test::More; use lib qw(t/lib); use DBICTest; use B::Deparse; +use DBIx::Class::_Util 'perlstring'; # globally set for the rest of test # the rowparser maker does not order its hashes by default for the miniscule @@ -21,9 +22,9 @@ my $infmap = [qw/ /]; is_same_src ( - $schema->source ('CD')->_mk_row_parser({ + ($schema->source ('CD')->_mk_row_parser({ inflate_map => $infmap, - }), + }))[0], '$_ = [ { year => $_->[1] }, { single_track => ( ! defined( $_->[0]) ) @@ -60,9 +61,9 @@ $infmap = [qw/ /]; is_same_src ( - $schema->source ('CD')->_mk_row_parser({ + ($schema->source ('CD')->_mk_row_parser({ inflate_map => $infmap, - }), + }))[0], '$_ = [ { artist => $_->[5], title => $_->[4], year => $_->[2] }, { @@ -137,10 +138,47 @@ is_same_src ( ); is_same_src ( - $schema->source ('CD')->_mk_row_parser({ + ($schema->source ('CD')->_mk_row_parser({ + prune_null_branches => 1, + inflate_map => $infmap, + }))[0], + '$_ = [ + { artist => $_->[5], title => $_->[4], year => $_->[2] }, + { + single_track => ( (! defined $_->[0] ) && (! defined $_->[1]) && (! defined $_->[3] ) ) ? undef : [ + undef, + { + cd => [ + undef, + { + artist => [ + { artistid => $_->[1] }, + { + cds => ( (! defined $_->[0] ) && ( ! defined $_->[3] ) ) ? undef : [ + { cdid => $_->[3] }, + { + tracks => ( ! defined $_->[0] ) ? undef : [ + { title => $_->[0] }, + ] + } + ] + } + ] + } + ] + } + ] + } + ] for @{$_[0]}', + '1:1 descending non-collapsing pruning parser terminating with chained 1:M:M', +); + +is_same_src ( + ($schema->source ('CD')->_mk_row_parser({ hri_style => 1, + prune_null_branches => 1, inflate_map => $infmap, - }), + }))[0], '$_ = { artist => $_->[5], title => $_->[4], year => $_->[2], @@ -206,53 +244,70 @@ is_deeply ( ); is_same_src ( - $schema->source ('CD')->_mk_row_parser({ + ($schema->source ('CD')->_mk_row_parser({ inflate_map => $infmap, collapse => 1, - }), + }))[0], ' my $rows_pos = 0; my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids); while ($cur_row_data = ( - ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } ) - || + ( + $rows_pos >= 0 + and + ( + $_[0][$rows_pos++] + or + ( ($rows_pos = -1), undef ) + ) + ) + or ( $_[1] and $_[1]->() ) - ) { + ) ) { - $cur_row_ids{$_} = defined $cur_row_data->[$_] ? $cur_row_data->[$_] : "\0NULL\xFF$rows_pos\xFF$_\0" - for (0, 1, 3, 4, 5); + ( @cur_row_ids{0,1,3,4,5} = ( + ( $cur_row_data->[0] // "\0NULL\xFF$rows_pos\xFF0\0" ), + ( $cur_row_data->[1] // "\0NULL\xFF$rows_pos\xFF1\0" ), + ( $cur_row_data->[3] // "\0NULL\xFF$rows_pos\xFF3\0" ), + ( $cur_row_data->[4] // "\0NULL\xFF$rows_pos\xFF4\0" ), + ( $cur_row_data->[5] // "\0NULL\xFF$rows_pos\xFF5\0" ), + ) ), # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2] - $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}} and (unshift @{$_[2]}, $cur_row_data) and last; + ( $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}} and (unshift @{$_[2]}, $cur_row_data) and last ), # the rowdata itself for root node - $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] }]; + ( $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] }] ), # prefetch data of single_track (placed in root) - $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}} = []; - defined($cur_row_data->[1]) or bless( $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{single_track}, __NBC__ ); + ( $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}} = [] ), + ( defined($cur_row_data->[1]) or bless( $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{single_track}, __NBC__ ) ), # prefetch data of cd (placed in single_track) - $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}} = []; + ( $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}} = [] ), # prefetch data of artist ( placed in single_track->cd) - $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] }]; + ( $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] }] ), # prefetch data of cds (if available) - (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} ) - and - push @{$collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{cds}}, ( - $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} = [{ cdid => $cur_row_data->[3] }] - ); - 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__ ); + ( + (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} ) + and + push @{$collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{cds}}, ( + $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} = [{ cdid => $cur_row_data->[3] }] + ) + ), + ( 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__ ) ), # prefetch data of tracks (if available) - (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} ) - and - push @{$collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{tracks}}, ( - $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] }] - ); - 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__ ); + ( + (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} ) + and + push @{$collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{tracks}}, ( + $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] }] + ) + ), + ( 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__ ) ), } $#{$_[0]} = $result_pos - 1; @@ -261,56 +316,71 @@ is_same_src ( ); is_same_src ( - $schema->source ('CD')->_mk_row_parser({ + ($schema->source ('CD')->_mk_row_parser({ inflate_map => $infmap, collapse => 1, hri_style => 1, - }), + prune_null_branches => 1, + }))[0], ' my $rows_pos = 0; - my ($result_pos, @collapse_idx, $cur_row_data); + my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids); while ($cur_row_data = ( - ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } ) - || + ( + $rows_pos >= 0 + and + ( + $_[0][$rows_pos++] + or + ( ($rows_pos = -1), undef ) + ) + ) + or ( $_[1] and $_[1]->() ) - ) { + ) ) { + + ( @cur_row_ids{0, 1, 3, 4, 5} = @{$cur_row_data}[0, 1, 3, 4, 5] ), # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2] - $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_data->[4]}{$cur_row_data->[5]} and (unshift @{$_[2]}, $cur_row_data) and last; + ( $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}} and (unshift @{$_[2]}, $cur_row_data) and last ), # the rowdata itself for root node - $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] }; + ( $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] } ), # prefetch data of single_track (placed in root) - (! defined($cur_row_data->[1]) ) ? $collapse_idx[0]{$cur_row_data->[4]}{$cur_row_data->[5]}{single_track} = undef : do { - $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]}; + ( (! defined($cur_row_data->[1]) ) ? $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}}{single_track} = undef : do { + ( $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}} ), # prefetch data of cd (placed in single_track) - $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]}; + ( $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}} ), # prefetch data of artist ( placed in single_track->cd) - $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] }; + ( $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] } ), # prefetch data of cds (if available) - (! defined $cur_row_data->[3] ) ? $collapse_idx[3]{$cur_row_data->[1]}{$cur_row_data->[4]}{$cur_row_data->[5]}{cds} = [] : do { + ( (! defined $cur_row_data->[3] ) ? $collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}{cds} = [] : do { - (! $collapse_idx[4]{$cur_row_data->[1]}{$cur_row_data->[3]}{$cur_row_data->[4]}{$cur_row_data->[5]} ) - and - push @{$collapse_idx[3]{$cur_row_data->[1]}{$cur_row_data->[4]}{$cur_row_data->[5]}{cds}}, ( - $collapse_idx[4]{$cur_row_data->[1]}{$cur_row_data->[3]}{$cur_row_data->[4]}{$cur_row_data->[5]} = { cdid => $cur_row_data->[3] } - ); + ( + (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} ) + and + push @{$collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}{cds}}, ( + $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} = { cdid => $cur_row_data->[3] } + ) + ), # prefetch data of tracks (if available) - ( ! 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 { - - (! $collapse_idx[5]{$cur_row_data->[0]}{$cur_row_data->[1]}{$cur_row_data->[3]}{$cur_row_data->[4]}{$cur_row_data->[5]} ) - and - push @{$collapse_idx[4]{$cur_row_data->[1]}{$cur_row_data->[3]}{$cur_row_data->[4]}{$cur_row_data->[5]}{tracks}}, ( - $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] } - ); - }; - }; - }; + (( ! defined $cur_row_data->[0] ) ? $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}}{tracks} = [] : do { + + ( + (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} ) + and + push @{$collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}}{tracks}}, ( + $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] } + ) + ), + } ), + } ), + } ), } $#{$_[0]} = $result_pos - 1; ', @@ -379,60 +449,82 @@ is_deeply ( ); is_same_src ( - $schema->source ('CD')->_mk_row_parser({ + ($schema->source ('CD')->_mk_row_parser({ inflate_map => $infmap, collapse => 1, - }), + }))[0], ' my $rows_pos = 0; my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids); while ($cur_row_data = ( - ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } ) - || + ( + $rows_pos >= 0 + and + ( + $_[0][$rows_pos++] + or + ( ($rows_pos = -1), undef ) + ) + ) + or ( $_[1] and $_[1]->() ) - ) { + ) ) { - $cur_row_ids{$_} = defined $cur_row_data->[$_] ? $cur_row_data->[$_] : "\0NULL\xFF$rows_pos\xFF$_\0" - for (0, 1, 5, 6, 8, 10); + ( @cur_row_ids{0, 1, 5, 6, 8, 10} = ( + $cur_row_data->[0] // "\0NULL\xFF$rows_pos\xFF0\0", + $cur_row_data->[1] // "\0NULL\xFF$rows_pos\xFF1\0", + $cur_row_data->[5] // "\0NULL\xFF$rows_pos\xFF5\0", + $cur_row_data->[6] // "\0NULL\xFF$rows_pos\xFF6\0", + $cur_row_data->[8] // "\0NULL\xFF$rows_pos\xFF8\0", + $cur_row_data->[10] // "\0NULL\xFF$rows_pos\xFF10\0", + ) ), # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2] - $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{1}} and (unshift @{$_[2]}, $cur_row_data) and last; - - $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] }]; - - $collapse_idx[0]{$cur_row_ids{1}}[1]{existing_single_track} ||= $collapse_idx[1]{$cur_row_ids{1}} = []; - $collapse_idx[1]{$cur_row_ids{1}}[1]{cd} ||= $collapse_idx[2]{$cur_row_ids{1}} = []; - $collapse_idx[2]{$cur_row_ids{1}}[1]{artist} ||= $collapse_idx[3]{$cur_row_ids{1}} = [{ artistid => $cur_row_data->[1] }]; - - (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}} ) - and - push @{ $collapse_idx[3]{$cur_row_ids{1}}[1]{cds} }, ( - $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] }] - ); - defined($cur_row_data->[6]) or bless( $collapse_idx[3]{$cur_row_ids{1}}[1]{cds}, __NBC__ ); - - (! $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} ) - and - push @{ $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} }, ( - $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }] - ); - defined($cur_row_data->[8]) or bless( $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks}, __NBC__ ); - - (! $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} ) - and - push @{ $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} }, ( - $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} = [{ title => $cur_row_data->[5] }] - ); - defined($cur_row_data->[5]) or bless( $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks}, __NBC__ ); - - $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}} = []; - defined($cur_row_data->[10]) or bless( $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}}[1]{lyrics}, __NBC__ ); - - (! $collapse_idx[8]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} ) - and - push @{ $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}}[1]{existing_lyric_versions} }, ( - $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] }] - ); + ( $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{1}} and (unshift @{$_[2]}, $cur_row_data) and last ), + + ( $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] }] ), + + ( $collapse_idx[0]{$cur_row_ids{1}}[1]{existing_single_track} //= $collapse_idx[1]{$cur_row_ids{1}} = [] ), + ( $collapse_idx[1]{$cur_row_ids{1}}[1]{cd} //= $collapse_idx[2]{$cur_row_ids{1}} = [] ), + ( $collapse_idx[2]{$cur_row_ids{1}}[1]{artist} //= $collapse_idx[3]{$cur_row_ids{1}} = [{ artistid => $cur_row_data->[1] }] ), + + ( + (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}} ) + and + push @{ $collapse_idx[3]{$cur_row_ids{1}}[1]{cds} }, ( + $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] }] + ) + ), + ( defined($cur_row_data->[6]) or bless( $collapse_idx[3]{$cur_row_ids{1}}[1]{cds}, __NBC__ ) ), + + ( + (! $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} ) + and + push @{ $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} }, ( + $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }] + ) + ), + ( defined($cur_row_data->[8]) or bless( $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks}, __NBC__ ) ), + + ( + (! $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} ) + and + push @{ $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} }, ( + $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} = [{ title => $cur_row_data->[5] }] + ) + ), + ( defined($cur_row_data->[5]) or bless( $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks}, __NBC__ ) ), + + ( $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}} = [] ), + ( defined($cur_row_data->[10]) or bless( $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}}[1]{lyrics}, __NBC__ ) ), + + ( + (! $collapse_idx[8]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} ) + and + push @{ $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}}[1]{existing_lyric_versions} }, ( + $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] }] + ) + ), } $#{$_[0]} = $result_pos - 1; @@ -441,65 +533,87 @@ is_same_src ( ); is_same_src ( - $schema->source ('CD')->_mk_row_parser({ + ($schema->source ('CD')->_mk_row_parser({ inflate_map => $infmap, collapse => 1, - }), + prune_null_branches => 1, + }))[0], ' my $rows_pos = 0; my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids); while ($cur_row_data = ( - ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } ) - || + ( + $rows_pos >= 0 + and + ( + $_[0][$rows_pos++] + or + ( ($rows_pos = -1), undef ) + ) + ) + or ( $_[1] and $_[1]->() ) - ) { + ) ) { - $cur_row_ids{$_} = defined $cur_row_data->[$_] ? $cur_row_data->[$_] : "\0NULL\xFF$rows_pos\xFF$_\0" - for (0, 1, 5, 6, 8, 10); + ( @cur_row_ids{( 0, 1, 5, 6, 8, 10 )} = @{$cur_row_data}[( 0, 1, 5, 6, 8, 10 )] ), # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2] - $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{1}} and (unshift @{$_[2]}, $cur_row_data) and last; - - $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] }]; - - $collapse_idx[0]{$cur_row_ids{1}}[1]{existing_single_track} ||= $collapse_idx[1]{$cur_row_ids{1}} = []; - $collapse_idx[1]{$cur_row_ids{1}}[1]{cd} ||= $collapse_idx[2]{$cur_row_ids{1}} = []; - $collapse_idx[2]{$cur_row_ids{1}}[1]{artist} ||= $collapse_idx[3]{$cur_row_ids{1}} = [{ artistid => $cur_row_data->[1] }]; - - (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}} ) - and - push @{ $collapse_idx[3]{$cur_row_ids{1}}[1]{cds} }, ( - $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] }] - ); - defined($cur_row_data->[6]) or bless( $collapse_idx[3]{$cur_row_ids{1}}[1]{cds}, __NBC__ ); - - (! $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} ) - and - push @{ $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} }, ( - $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }] - ); - defined($cur_row_data->[8]) or bless( $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks}, __NBC__ ); - - (! $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} ) - and - push @{ $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} }, ( - $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} = [{ title => $cur_row_data->[5] }] - ); - defined($cur_row_data->[5]) or bless( $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks}, __NBC__ ); - - $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}} = []; - defined($cur_row_data->[10]) or bless( $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}}[1]{lyrics}, __NBC__ ); - - (! $collapse_idx[8]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} ) - and - push @{ $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}}[1]{existing_lyric_versions} }, ( - $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] }] - ); + ( $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{1}} and (unshift @{$_[2]}, $cur_row_data) and last ), + + ( $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] }] ), + + ( $collapse_idx[0]{$cur_row_ids{1}}[1]{existing_single_track} //= $collapse_idx[1]{$cur_row_ids{1}} = [] ), + ( $collapse_idx[1]{$cur_row_ids{1}}[1]{cd} //= $collapse_idx[2]{$cur_row_ids{1}} = [] ), + ( $collapse_idx[2]{$cur_row_ids{1}}[1]{artist} //= $collapse_idx[3]{$cur_row_ids{1}} = [{ artistid => $cur_row_data->[1] }] ), + + ( (! defined($cur_row_data->[6])) ? $collapse_idx[3]{$cur_row_ids{1}}[1]{cds} = [] : do { + ( + (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}} ) + and + push @{ $collapse_idx[3]{$cur_row_ids{1}}[1]{cds} }, ( + $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] }] + ) + ), + + ( (! defined($cur_row_data->[8]) ) ? $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} = [] : do { + ( + (! $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} ) + and + push @{ $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} }, ( + $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }] + ) + ), + } ), + } ), + + ( (! defined($cur_row_data->[5]) ) ? $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} = [] : do { + + ( + (! $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} ) + and + push @{ $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} }, ( + $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} = [{ title => $cur_row_data->[5] }] + ) + ), + + ( (! defined($cur_row_data->[10]) ) ? $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}}[1]{lyrics} = [] : do { + + ( $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}} = [] ), + + ( + (! $collapse_idx[8]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} ) + and + push @{ $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}}[1]{existing_lyric_versions} }, ( + $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] }] + ) + ), + } ), + } ), } $#{$_[0]} = $result_pos - 1; ', - 'Multiple has_many on multiple branches with branch torture test', + 'Multiple has_many on multiple branches with branch pruning torture test', ); $infmap = [ @@ -551,63 +665,82 @@ is_deeply ( ); is_same_src ( - $schema->source ('CD')->_mk_row_parser({ + ($schema->source ('CD')->_mk_row_parser({ inflate_map => $infmap, collapse => 1, - }), + }))[0], ' my $rows_pos = 0; my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids); while ($cur_row_data = ( - ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } ) - || + ( + $rows_pos >= 0 + and + ( + $_[0][$rows_pos++] + or + ( ($rows_pos = -1), undef ) + ) + ) + or ( $_[1] and $_[1]->() ) - ) { + ) ) { - $cur_row_ids{$_} = defined $$cur_row_data[$_] ? $$cur_row_data[$_] : "\0NULL\xFF$rows_pos\xFF$_\0" - for (0, 2, 3, 4, 8); + ( @cur_row_ids{( 0, 2, 3, 4, 8 )} = ( + $cur_row_data->[0] // "\0NULL\xFF$rows_pos\xFF0\0", + $cur_row_data->[2] // "\0NULL\xFF$rows_pos\xFF2\0", + $cur_row_data->[3] // "\0NULL\xFF$rows_pos\xFF3\0", + $cur_row_data->[4] // "\0NULL\xFF$rows_pos\xFF4\0", + $cur_row_data->[8] // "\0NULL\xFF$rows_pos\xFF8\0", + )), # cache expensive set of ops in a non-existent rowid slot - $cur_row_ids{10} = ( - ( ( defined $cur_row_data->[0] ) && (join "\xFF", q{}, $cur_row_data->[0], q{} )) + ( $cur_row_ids{10} = ( + ( ( defined $cur_row_data->[0] ) && (join "\xFF", q{}, $cur_row_ids{0}, q{} )) or - ( ( defined $cur_row_data->[2] ) && (join "\xFF", q{}, $cur_row_data->[2], q{} )) + ( ( defined $cur_row_data->[2] ) && (join "\xFF", q{}, $cur_row_ids{2}, q{} )) or "\0$rows_pos\0" - ); + )), # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2] - $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{10}} and (unshift @{$_[2]}, $cur_row_data) and last; + ( $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{10}} and (unshift @{$_[2]}, $cur_row_data) and last ), - $collapse_idx[0]{$cur_row_ids{10}} ||= $_[0][$result_pos++] = [{ year => $$cur_row_data[1] }]; + ( $collapse_idx[0]{$cur_row_ids{10}} //= $_[0][$result_pos++] = [{ year => $$cur_row_data[1] }] ), - $collapse_idx[0]{$cur_row_ids{10}}[1]{single_track} ||= ($collapse_idx[1]{$cur_row_ids{0}} = [{ trackid => $cur_row_data->[0] }]); - defined($cur_row_data->[0]) or bless ( $collapse_idx[0]{$cur_row_ids{10}}[1]{single_track}, __NBC__ ); + ( $collapse_idx[0]{$cur_row_ids{10}}[1]{single_track} //= ($collapse_idx[1]{$cur_row_ids{0}} = [{ trackid => $cur_row_data->[0] }]) ), + ( defined($cur_row_data->[0]) or bless ( $collapse_idx[0]{$cur_row_ids{10}}[1]{single_track}, __NBC__ ) ), - $collapse_idx[1]{$cur_row_ids{0}}[1]{cd} ||= $collapse_idx[2]{$cur_row_ids{0}} = []; + ( $collapse_idx[1]{$cur_row_ids{0}}[1]{cd} //= $collapse_idx[2]{$cur_row_ids{0}} = [] ), - $collapse_idx[2]{$cur_row_ids{0}}[1]{artist} ||= ($collapse_idx[3]{$cur_row_ids{0}} = [{ artistid => $cur_row_data->[6] }]); + ( $collapse_idx[2]{$cur_row_ids{0}}[1]{artist} //= ($collapse_idx[3]{$cur_row_ids{0}} = [{ artistid => $cur_row_data->[6] }]) ), - (! $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}} ) - and - push @{$collapse_idx[3]{$cur_row_ids{0}}[1]{cds}}, ( + ( + (! $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}} ) + and + push @{$collapse_idx[3]{$cur_row_ids{0}}[1]{cds}}, ( $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] }] - ); - defined($cur_row_data->[4]) or bless ( $collapse_idx[3]{$cur_row_ids{0}}[1]{cds}, __NBC__ ); - - (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} ) - and - push @{$collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}[1]{tracks}}, ( - $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }] - ); - defined($cur_row_data->[8]) or bless ( $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}[1]{tracks}, __NBC__ ); - - (! $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} ) - and - push @{$collapse_idx[0]{$cur_row_ids{10}}[1]{tracks}}, ( + ) + ), + ( defined($cur_row_data->[4]) or bless ( $collapse_idx[3]{$cur_row_ids{0}}[1]{cds}, __NBC__ ) ), + + ( + (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} ) + and + push @{$collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}[1]{tracks}}, ( + $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }] + ) + ), + ( defined($cur_row_data->[8]) or bless ( $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}[1]{tracks}, __NBC__ ) ), + + ( + (! $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} ) + and + push @{$collapse_idx[0]{$cur_row_ids{10}}[1]{tracks}}, ( $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} = [{ cd => $$cur_row_data[2], title => $cur_row_data->[3] }] - ); - defined($cur_row_data->[2]) or bless ( $collapse_idx[0]{$cur_row_ids{10}}[1]{tracks}, __NBC__ ); + ) + ), + ( defined($cur_row_data->[2]) or bless ( $collapse_idx[0]{$cur_row_ids{10}}[1]{tracks}, __NBC__ ) ), } $#{$_[0]} = $result_pos - 1; @@ -616,68 +749,84 @@ is_same_src ( ); is_same_src ( - $schema->source ('CD')->_mk_row_parser({ + ($schema->source ('CD')->_mk_row_parser({ inflate_map => $infmap, collapse => 1, hri_style => 1, - }), + prune_null_branches => 1, + }))[0], ' my $rows_pos = 0; - my ($result_pos, @collapse_idx, $cur_row_data); + my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids); while ($cur_row_data = ( - ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } ) - || + ( + $rows_pos >= 0 + and + ( + $_[0][$rows_pos++] + or + ( ($rows_pos = -1), undef ) + ) + ) + or ( $_[1] and $_[1]->() ) - ) { + ) ) { + + # do not care about nullability here + ( @cur_row_ids{( 0, 2, 3, 4, 8 )} = @{$cur_row_data}[( 0, 2, 3, 4, 8 )] ), # cache expensive set of ops in a non-existent rowid slot - $cur_row_data->[10] = ( - ( ( defined $cur_row_data->[0] ) && (join "\xFF", q{}, $cur_row_data->[0], q{} )) + ( $cur_row_ids{10} = ( + ( ( defined $cur_row_data->[0] ) && (join "\xFF", q{}, $cur_row_ids{0}, q{} )) or - ( ( defined $cur_row_data->[2] ) && (join "\xFF", q{}, $cur_row_data->[2], q{} )) + ( ( defined $cur_row_data->[2] ) && (join "\xFF", q{}, $cur_row_ids{2}, q{} )) or "\0$rows_pos\0" - ); + )), # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2] - $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_data->[10]} and (unshift @{$_[2]}, $cur_row_data) and last; + ( $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{10}} and (unshift @{$_[2]}, $cur_row_data) and last ), - $collapse_idx[0]{$cur_row_data->[10]} ||= $_[0][$result_pos++] = { year => $$cur_row_data[1] }; + ( $collapse_idx[0]{$cur_row_ids{10}} //= $_[0][$result_pos++] = { year => $$cur_row_data[1] } ), - (! defined $cur_row_data->[0] ) ? $collapse_idx[0]{$cur_row_data->[10]}{single_track} = undef : do { + ( (! defined $cur_row_data->[0] ) ? $collapse_idx[0]{$cur_row_ids{10}}{single_track} = undef : do { - $collapse_idx[0]{$cur_row_data->[10]}{single_track} ||= ($collapse_idx[1]{$cur_row_data->[0]} = { trackid => $$cur_row_data[0] }); + ( $collapse_idx[0]{$cur_row_ids{10}}{single_track} //= ($collapse_idx[1]{$cur_row_ids{0}} = { trackid => $$cur_row_data[0] }) ), - $collapse_idx[1]{$cur_row_data->[0]}{cd} ||= $collapse_idx[2]{$cur_row_data->[0]}; + ( $collapse_idx[1]{$cur_row_ids{0}}{cd} //= $collapse_idx[2]{$cur_row_ids{0}} ), - $collapse_idx[2]{$cur_row_data->[0]}{artist} ||= ($collapse_idx[3]{$cur_row_data->[0]} = { artistid => $$cur_row_data[6] }); + ( $collapse_idx[2]{$cur_row_ids{0}}{artist} //= ($collapse_idx[3]{$cur_row_ids{0}} = { artistid => $$cur_row_data[6] }) ), - (! defined $cur_row_data->[4] ) ? $collapse_idx[3]{$cur_row_data->[0]}{cds} = [] : do { + ( (! defined $cur_row_data->[4] ) ? $collapse_idx[3]{$cur_row_ids{0}}{cds} = [] : do { - (! $collapse_idx[4]{$cur_row_data->[0]}{$cur_row_data->[4]} ) - and - push @{$collapse_idx[3]{$cur_row_data->[0]}{cds}}, ( - $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] } - ); + ( + (! $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}} ) + and + push @{$collapse_idx[3]{$cur_row_ids{0}}{cds}}, ( + $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] } + ) + ), - (! defined $cur_row_data->[8] ) ? $collapse_idx[4]{$cur_row_data->[0]}{$cur_row_data->[4]}{tracks} = [] : do { + ( (! defined $cur_row_data->[8] ) ? $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}{tracks} = [] : do { - (! $collapse_idx[5]{$cur_row_data->[0]}{$cur_row_data->[4]}{$cur_row_data->[8]} ) + (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} ) and - push @{$collapse_idx[4]{$cur_row_data->[0]}{$cur_row_data->[4]}{tracks}}, ( - $collapse_idx[5]{$cur_row_data->[0]}{$cur_row_data->[4]}{$cur_row_data->[8]} = { title => $$cur_row_data[8] } - ); - }; - }; - }; - - (! defined $cur_row_data->[2] ) ? $collapse_idx[0]{$cur_row_data->[10]}{tracks} = [] : do { - (! $collapse_idx[6]{$cur_row_data->[2]}{$cur_row_data->[3]} ) - and - push @{$collapse_idx[0]{$cur_row_data->[10]}{tracks}}, ( - $collapse_idx[6]{$cur_row_data->[2]}{$cur_row_data->[3]} = { cd => $$cur_row_data[2], title => $$cur_row_data[3] } - ); - }; + push @{$collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}{tracks}}, ( + $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} = { title => $$cur_row_data[8] } + ), + } ), + } ), + } ), + + ( (! defined $cur_row_data->[2] ) ? $collapse_idx[0]{$cur_row_ids{10}}{tracks} = [] : do { + ( + (! $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} ) + and + push @{$collapse_idx[0]{$cur_row_ids{10}}{tracks}}, ( + $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} = { cd => $$cur_row_data[2], title => $$cur_row_data[3] } + ) + ), + } ), } $#{$_[0]} = $result_pos - 1; @@ -685,18 +834,73 @@ is_same_src ( 'Multiple has_many on multiple branches with underdefined root, HRI-direct torture test', ); +is_same_src ( + ($schema->source ('Owners')->_mk_row_parser({ + inflate_map => [qw( books.title books.owner )], + collapse => 1, + prune_null_branches => 1, + }))[0], + ' my $rows_pos = 0; + my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids ); + + while ($cur_row_data = ( + ( + $rows_pos >= 0 + and + ( + $_[0][$rows_pos++] + or + ( ($rows_pos = -1), undef ) + ) + ) + or + ( $_[1] and $_[1]->() ) + ) ) { + + ( @cur_row_ids{0,1} = @{$cur_row_data}[0,1] ), + + ( $cur_row_ids{3} = ( + ( ( defined $cur_row_data->[1] ) && (join "\xFF", q{}, $cur_row_ids{1}, q{} )) + or + "\0${rows_pos}\0" + )), + + ( $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{3}} and (unshift @{$_[2]}, $cur_row_data) and last ), + + # empty data for the root node + ( $collapse_idx[0]{$cur_row_ids{3}} //= $_[0][$result_pos++] = [] ), + + ( ( ! defined $cur_row_data->[0] ) ? $collapse_idx[0]{$cur_row_ids{3}}[1]{"books"} = [] : do { + push @{$collapse_idx[0]{$cur_row_ids{3}}[1]{books}}, + $collapse_idx[1]{$cur_row_ids{0}} = [ { owner => $cur_row_data->[1], title => $cur_row_data->[0] } ] + unless $collapse_idx[1]{$cur_row_ids{0}} + } ), + } + + $#{$_[0]} = $result_pos - 1; # truncate the passed in array to where we filled it with results + ', + 'Non-premultiplied implicit collapse with missing join columns', +); + done_testing; my $deparser; -sub is_same_src { +sub is_same_src { SKIP: { + + skip "Skipping comparison of unicode-posioned source", 1 + if DBIx::Class::_ENV_::STRESSTEST_UTF8_UPGRADE_GENERATED_COLLAPSER_SOURCE; + $deparser ||= B::Deparse->new; local $Test::Builder::Level = $Test::Builder::Level + 1; my ($got, $expect) = @_; - $expect =~ s/__NBC__/B::perlstring($DBIx::Class::ResultSource::RowParser::Util::null_branch_class)/ge; + skip "Not testing equality of source containing defined-or operator on this perl $]", 1 + if ($] < 5.010 and$expect =~ m!\Q//=!); + + $expect =~ s/__NBC__/perlstring($DBIx::Class::ResultSource::RowParser::Util::null_branch_class)/ge; - $expect = " { use strict; use warnings FATAL => 'all';\n$expect\n }"; + $expect = " { use strict; use warnings FATAL => 'uninitialized';\n$expect\n }"; my @normalized = map { my $cref = eval "sub { $_ }" or do { @@ -713,4 +917,4 @@ sub is_same_src { ; exit 1; }; -} +} }