X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=t%2Fresultset%2Frowparser_internals.t;h=646ead06889246c5f24a6e92024e2b112f7e55b8;hb=164aab8c48e5a055da6b395893fd10326961acee;hp=c53b3ebd398e76333afdd3477cf8b7279e23b522;hpb=cd784aab86565e35c3aa9ba13fa2ea3e95616ec3;p=dbsrgits%2FDBIx-Class.git diff --git a/t/resultset/rowparser_internals.t b/t/resultset/rowparser_internals.t index c53b3eb..646ead0 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,10 @@ 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] }, { @@ -173,11 +174,11 @@ is_same_src ( ); is_same_src ( - $schema->source ('CD')->_mk_row_parser({ + ($schema->source ('CD')->_mk_row_parser({ hri_style => 1, prune_null_branches => 1, inflate_map => $infmap, - }), + }))[0], '$_ = { artist => $_->[5], title => $_->[4], year => $_->[2], @@ -243,24 +244,34 @@ 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++] ) - || - ( $_[1] and $rows_pos = -1 and $_[1]->() ) + ( + $rows_pos >= 0 + and + ( + $_[0][$rows_pos++] + or + ( ($rows_pos = -1), undef ) + ) + ) + or + ( $_[1] and $_[1]->() ) ) ) { - $cur_row_ids{0} = $cur_row_data->[0] // "\0NULL\xFF$rows_pos\xFF0\0"; - $cur_row_ids{1} = $cur_row_data->[1] // "\0NULL\xFF$rows_pos\xFF1\0"; - $cur_row_ids{3} = $cur_row_data->[3] // "\0NULL\xFF$rows_pos\xFF3\0"; - $cur_row_ids{4} = $cur_row_data->[4] // "\0NULL\xFF$rows_pos\xFF4\0"; - $cur_row_ids{5} = $cur_row_data->[5] // "\0NULL\xFF$rows_pos\xFF5\0"; + @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; @@ -301,53 +312,63 @@ 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++] ) - || - ( $_[1] and $rows_pos = -1 and $_[1]->() ) + ( + $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]} ) + (! $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_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] } + 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 { + ( ! 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_data->[0]}{$cur_row_data->[1]}{$cur_row_data->[3]}{$cur_row_data->[4]}{$cur_row_data->[5]} ) + (! $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_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] } + 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] } ); }; }; @@ -420,25 +441,35 @@ 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++] ) - || - ( $_[1] and $rows_pos = -1 and $_[1]->() ) + ( + $rows_pos >= 0 + and + ( + $_[0][$rows_pos++] + or + ( ($rows_pos = -1), undef ) + ) + ) + or + ( $_[1] and $_[1]->() ) ) ) { - $cur_row_ids{0} = $cur_row_data->[0] // "\0NULL\xFF$rows_pos\xFF0\0"; - $cur_row_ids{1} = $cur_row_data->[1] // "\0NULL\xFF$rows_pos\xFF1\0"; - $cur_row_ids{5} = $cur_row_data->[5] // "\0NULL\xFF$rows_pos\xFF5\0"; - $cur_row_ids{6} = $cur_row_data->[6] // "\0NULL\xFF$rows_pos\xFF6\0"; - $cur_row_ids{8} = $cur_row_data->[8] // "\0NULL\xFF$rows_pos\xFF8\0"; - $cur_row_ids{10} = $cur_row_data->[10] // "\0NULL\xFF$rows_pos\xFF10\0"; + @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; @@ -486,62 +517,72 @@ 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); + my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids); while ($cur_row_data = ( - ( $rows_pos >= 0 and $_[0][$rows_pos++] ) - || - ( $_[1] and $rows_pos = -1 and $_[1]->() ) + ( + $rows_pos >= 0 + and + ( + $_[0][$rows_pos++] + or + ( ($rows_pos = -1), undef ) + ) + ) + or + ( $_[1] and $_[1]->() ) ) ) { + @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_data->[1]} and (unshift @{$_[2]}, $cur_row_data) and last; + $_[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_data->[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}} //= $_[0][$result_pos++] = [{ genreid => $cur_row_data->[4], latest_cd => $cur_row_data->[7], year => $cur_row_data->[3] }]; - $collapse_idx[0]{$cur_row_data->[1]}[1]{existing_single_track} //= $collapse_idx[1]{$cur_row_data->[1]} = []; - $collapse_idx[1]{$cur_row_data->[1]}[1]{cd} //= $collapse_idx[2]{$cur_row_data->[1]} = []; - $collapse_idx[2]{$cur_row_data->[1]}[1]{artist} //= $collapse_idx[3]{$cur_row_data->[1]} = [{ artistid => $cur_row_data->[1] }]; + $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_data->[1]}[1]{cds} = [] : do { - (! $collapse_idx[4]{$cur_row_data->[1]}{$cur_row_data->[6]} ) + (! 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_data->[1]}[1]{cds} }, ( - $collapse_idx[4]{$cur_row_data->[1]}{$cur_row_data->[6]} = [{ cdid => $cur_row_data->[6], genreid => $cur_row_data->[9], year => $cur_row_data->[2] }] + 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_data->[1]}{$cur_row_data->[6]}[1]{tracks} = [] : do { + (! defined($cur_row_data->[8]) ) ? $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} = [] : do { - (! $collapse_idx[5]{$cur_row_data->[1]}{$cur_row_data->[6]}{$cur_row_data->[8]} ) + (! $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} ) and - push @{ $collapse_idx[4]{$cur_row_data->[1]}{$cur_row_data->[6]}[1]{tracks} }, ( - $collapse_idx[5]{$cur_row_data->[1]}{$cur_row_data->[6]}{$cur_row_data->[8]} = [{ title => $cur_row_data->[8] }] + 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_data->[1]}[1]{tracks} = [] : do { + (! defined($cur_row_data->[5]) ) ? $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} = [] : do { - (! $collapse_idx[6]{$cur_row_data->[1]}{$cur_row_data->[5]} ) + (! $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} ) and - push @{ $collapse_idx[0]{$cur_row_data->[1]}[1]{tracks} }, ( - $collapse_idx[6]{$cur_row_data->[1]}{$cur_row_data->[5]} = [{ title => $cur_row_data->[5] }] + 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_data->[1]}{$cur_row_data->[5]}[1]{lyrics} = [] : do { + (! defined($cur_row_data->[10]) ) ? $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}}[1]{lyrics} = [] : do { - $collapse_idx[6]{$cur_row_data->[1]}{$cur_row_data->[5]}[1]{lyrics} //= $collapse_idx[7]{$cur_row_data->[1]}{$cur_row_data->[5]}{$cur_row_data->[10]} = []; + $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_data->[0]}{$cur_row_data->[1]}{$cur_row_data->[5]}{$cur_row_data->[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_data->[1]}{$cur_row_data->[5]}{$cur_row_data->[10]}[1]{existing_lyric_versions} }, ( - $collapse_idx[8]{$cur_row_data->[0]}{$cur_row_data->[1]}{$cur_row_data->[5]}{$cur_row_data->[10]} = [{ lyric_id => $cur_row_data->[10], text => $cur_row_data->[0] }] + 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] }] ); }; }; @@ -601,30 +642,40 @@ 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++] ) - || - ( $_[1] and $rows_pos = -1 and $_[1]->() ) + ( + $rows_pos >= 0 + and + ( + $_[0][$rows_pos++] + or + ( ($rows_pos = -1), undef ) + ) + ) + or + ( $_[1] and $_[1]->() ) ) ) { - $cur_row_ids{0} = $cur_row_data->[0] // "\0NULL\xFF$rows_pos\xFF0\0"; - $cur_row_ids{2} = $cur_row_data->[2] // "\0NULL\xFF$rows_pos\xFF2\0"; - $cur_row_ids{3} = $cur_row_data->[3] // "\0NULL\xFF$rows_pos\xFF3\0"; - $cur_row_ids{4} = $cur_row_data->[4] // "\0NULL\xFF$rows_pos\xFF4\0"; - $cur_row_ids{8} = $cur_row_data->[8] // "\0NULL\xFF$rows_pos\xFF8\0"; + @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{} )) + ( ( 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" ); @@ -669,33 +720,37 @@ 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, %cur_row_ids); while ($cur_row_data = ( - ( $rows_pos >= 0 and $_[0][$rows_pos++] ) - || - ( $_[1] and $rows_pos = -1 and $_[1]->() ) + ( + $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} = $cur_row_data->[0]; - $cur_row_ids{2} = $cur_row_data->[2]; - $cur_row_ids{3} = $cur_row_data->[3]; - $cur_row_ids{4} = $cur_row_data->[4]; - $cur_row_ids{8} = $cur_row_data->[8]; + @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_ids{10} = ( - ( ( defined $cur_row_data->[0] ) && (join "\xFF", q{}, $cur_row_data->[0], q{} )) + ( ( 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" ); @@ -746,10 +801,62 @@ 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 { 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; @@ -758,9 +865,9 @@ sub is_same_src { SKIP: { skip "Not testing equality of source containing defined-or operator on this perl $]", 1 if ($] < 5.010 and$expect =~ m!\Q//=!); - $expect =~ s/__NBC__/B::perlstring($DBIx::Class::ResultSource::RowParser::Util::null_branch_class)/ge; + $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 {