Make sure tests pass without a compiler present (another step to RT#74706)
[dbsrgits/DBIx-Class.git] / t / resultset / rowparser_internals.t
CommitLineData
4e9fc3f3 1use strict;
2use warnings;
3
4use Test::More;
5use lib qw(t/lib);
6use DBICTest;
7use B::Deparse;
01b25f12 8use DBIx::Class::_Util 'perlstring';
4e9fc3f3 9
7d5371dc 10# globally set for the rest of test
11# the rowparser maker does not order its hashes by default for the miniscule
12# speed gain. But it does not disable sorting either - for this test
13# everything will be ordered nicely, and the hash randomization of 5.18
14# will not trip up anything
15use Data::Dumper;
16$Data::Dumper::Sortkeys = 1;
17
4e9fc3f3 18my $schema = DBICTest->init_schema(no_deploy => 1);
ce556881 19my $infmap = [qw/
20 single_track.cd.artist.name
21 year
22/];
4e9fc3f3 23
24is_same_src (
02a73c96 25 ($schema->source ('CD')->_mk_row_parser({
4e9fc3f3 26 inflate_map => $infmap,
02a73c96 27 }))[0],
4e9fc3f3 28 '$_ = [
29 { year => $_->[1] },
52864fbd 30 { single_track => ( ! defined( $_->[0]) )
31 ? bless( [
4e9fc3f3 32 undef,
52864fbd 33 { cd => [
34 undef,
35 { artist => [
36 { name => $_->[0] },
37 ] },
4e9fc3f3 38 ] },
52864fbd 39 ], __NBC__ )
40 : [
41 undef,
42 { cd => [
43 undef,
44 { artist => [
45 { name => $_->[0] },
46 ] },
47 ] },
48 ]
49 },
4e9fc3f3 50 ] for @{$_[0]}',
51 'Simple 1:1 descending non-collapsing parser',
52);
53
54$infmap = [qw/
3faac878 55 single_track.cd.artist.cds.tracks.title
4e9fc3f3 56 single_track.cd.artist.artistid
57 year
4e9fc3f3 58 single_track.cd.artist.cds.cdid
59 title
60 artist
61/];
4e9fc3f3 62
ce556881 63is_same_src (
02a73c96 64 ($schema->source ('CD')->_mk_row_parser({
ce556881 65 inflate_map => $infmap,
02a73c96 66 }))[0],
ce556881 67 '$_ = [
68 { artist => $_->[5], title => $_->[4], year => $_->[2] },
69 {
52864fbd 70 single_track => ( (! defined $_->[0] ) && (! defined $_->[1]) && (! defined $_->[3] ) )
71 ? bless( [
72 undef,
73 {
74 cd => [
75 undef,
76 {
77 artist => [
78 { artistid => $_->[1] },
79 {
80 cds => ( (! defined $_->[0] ) && ( ! defined $_->[3] ) )
81 ? bless ([
82 { cdid => $_->[3] },
83 {
84 tracks => ( ! defined $_->[0] )
85 ? bless ( [{ title => $_->[0] }], __NBC__ )
86 : [{ title => $_->[0] }]
87 }
88 ], __NBC__)
89 : [
90 { cdid => $_->[3] },
91 {
92 tracks => ( ! defined $_->[0] )
93 ? bless ( [{ title => $_->[0] }], __NBC__ )
94 : [{ title => $_->[0] }]
95 }
96 ]
97 }
98 ]
99 }
100 ]
101 }
102 ], __NBC__)
103 : [
ce556881 104 undef,
105 {
106 cd => [
107 undef,
108 {
109 artist => [
110 { artistid => $_->[1] },
111 {
52864fbd 112 cds => ( (! defined $_->[0] ) && ( ! defined $_->[3] ) )
113 ? bless ([
114 { cdid => $_->[3] },
115 {
116 tracks => ( ! defined $_->[0] )
117 ? bless ( [{ title => $_->[0] }], __NBC__ )
118 : [{ title => $_->[0] }]
119 }
120 ], __NBC__)
121 : [
ce556881 122 { cdid => $_->[3] },
123 {
52864fbd 124 tracks => ( ! defined $_->[0] )
125 ? bless ( [{ title => $_->[0] }], __NBC__ )
126 : [{ title => $_->[0] }]
ce556881 127 }
52864fbd 128 ]
ce556881 129 }
130 ]
131 }
132 ]
133 }
52864fbd 134 ]
ce556881 135 }
136 ] for @{$_[0]}',
52864fbd 137 '1:1 descending non-collapsing parser terminating with chained 1:M:M',
ce556881 138);
139
140is_same_src (
02a73c96 141 ($schema->source ('CD')->_mk_row_parser({
79adc44f 142 prune_null_branches => 1,
143 inflate_map => $infmap,
02a73c96 144 }))[0],
79adc44f 145 '$_ = [
146 { artist => $_->[5], title => $_->[4], year => $_->[2] },
147 {
148 single_track => ( (! defined $_->[0] ) && (! defined $_->[1]) && (! defined $_->[3] ) ) ? undef : [
149 undef,
150 {
151 cd => [
152 undef,
153 {
154 artist => [
155 { artistid => $_->[1] },
156 {
157 cds => ( (! defined $_->[0] ) && ( ! defined $_->[3] ) ) ? undef : [
158 { cdid => $_->[3] },
159 {
160 tracks => ( ! defined $_->[0] ) ? undef : [
161 { title => $_->[0] },
162 ]
163 }
164 ]
165 }
166 ]
167 }
168 ]
169 }
170 ]
171 }
172 ] for @{$_[0]}',
173 '1:1 descending non-collapsing pruning parser terminating with chained 1:M:M',
174);
175
176is_same_src (
02a73c96 177 ($schema->source ('CD')->_mk_row_parser({
ce556881 178 hri_style => 1,
79adc44f 179 prune_null_branches => 1,
ce556881 180 inflate_map => $infmap,
02a73c96 181 }))[0],
ce556881 182 '$_ = {
183 artist => $_->[5], title => $_->[4], year => $_->[2],
184
52864fbd 185 ( single_track => ( (! defined $_->[0] ) && (! defined $_->[1]) && (! defined $_->[3] ) )
186 ? undef
187 : {
ce556881 188 cd =>
189 {
190 artist => {
191 artistid => $_->[1],
52864fbd 192 ( cds => ( (! defined $_->[0] ) && ( ! defined $_->[3] ) )
193 ? undef
194 : {
ce556881 195 cdid => $_->[3],
52864fbd 196 ( tracks => ( ! defined $_->[0] )
197 ? undef
198 : { title => $_->[0] }
199 )
ce556881 200 }
52864fbd 201 )
ce556881 202 }
203 }
204 }
52864fbd 205 )
ce556881 206 } for @{$_[0]}',
52864fbd 207 '1:1 descending non-collapsing HRI-direct parser terminating with chained 1:M:M',
ce556881 208);
209
210
211
4e9fc3f3 212is_deeply (
3faac878 213 ($schema->source('CD')->_resolve_collapse({ as => {map { $infmap->[$_] => $_ } 0 .. $#$infmap} })),
4e9fc3f3 214 {
9f98c4b2 215 -identifying_columns => [ 4, 5 ],
4e9fc3f3 216
217 single_track => {
a0726a33 218 -identifying_columns => [ 1, 4, 5 ],
4e9fc3f3 219 -is_optional => 1,
220 -is_single => 1,
221
222 cd => {
a0726a33 223 -identifying_columns => [ 1, 4, 5 ],
4e9fc3f3 224 -is_single => 1,
225
226 artist => {
a0726a33 227 -identifying_columns => [ 1, 4, 5 ],
4e9fc3f3 228 -is_single => 1,
229
230 cds => {
a0726a33 231 -identifying_columns => [ 1, 3, 4, 5 ],
4e9fc3f3 232 -is_optional => 1,
233
234 tracks => {
a0726a33 235 -identifying_columns => [ 0, 1, 3, 4, 5 ],
4e9fc3f3 236 -is_optional => 1,
237 },
238 },
239 },
240 },
241 },
242 },
243 'Correct collapse map for 1:1 descending chain terminating with chained 1:M:M'
244);
245
246is_same_src (
02a73c96 247 ($schema->source ('CD')->_mk_row_parser({
4e9fc3f3 248 inflate_map => $infmap,
249 collapse => 1,
02a73c96 250 }))[0],
aa1d8a87 251 ' my $rows_pos = 0;
252 my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids);
4e9fc3f3 253
9f98c4b2 254 while ($cur_row_data = (
3b4cd124 255 ( $rows_pos >= 0 and $_[0][$rows_pos++] )
4e9fc3f3 256 ||
3b4cd124 257 ( $_[1] and $rows_pos = -1 and $_[1]->() )
258 ) ) {
4e9fc3f3 259
cd784aab 260 $cur_row_ids{0} = $cur_row_data->[0] // "\0NULL\xFF$rows_pos\xFF0\0";
261 $cur_row_ids{1} = $cur_row_data->[1] // "\0NULL\xFF$rows_pos\xFF1\0";
262 $cur_row_ids{3} = $cur_row_data->[3] // "\0NULL\xFF$rows_pos\xFF3\0";
263 $cur_row_ids{4} = $cur_row_data->[4] // "\0NULL\xFF$rows_pos\xFF4\0";
264 $cur_row_ids{5} = $cur_row_data->[5] // "\0NULL\xFF$rows_pos\xFF5\0";
4e9fc3f3 265
3faac878 266 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
aa1d8a87 267 $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}} and (unshift @{$_[2]}, $cur_row_data) and last;
4e9fc3f3 268
3faac878 269 # the rowdata itself for root node
cd784aab 270 $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] }];
3faac878 271
272 # prefetch data of single_track (placed in root)
cd784aab 273 $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}} = [];
52864fbd 274 defined($cur_row_data->[1]) or bless( $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{single_track}, __NBC__ );
3faac878 275
276 # prefetch data of cd (placed in single_track)
cd784aab 277 $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}} = [];
4e9fc3f3 278
3faac878 279 # prefetch data of artist ( placed in single_track->cd)
cd784aab 280 $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] }];
3faac878 281
282 # prefetch data of cds (if available)
ce556881 283 (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} )
284 and
285 push @{$collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{cds}}, (
286 $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} = [{ cdid => $cur_row_data->[3] }]
287 );
52864fbd 288 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__ );
4e9fc3f3 289
3faac878 290 # prefetch data of tracks (if available)
ce556881 291 (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} )
292 and
293 push @{$collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{tracks}}, (
294 $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] }]
295 );
52864fbd 296 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__ );
4e9fc3f3 297
4e9fc3f3 298 }
aa1d8a87 299 $#{$_[0]} = $result_pos - 1;
4e9fc3f3 300 ',
301 'Same 1:1 descending terminating with chained 1:M:M but with collapse',
302);
303
ce556881 304is_same_src (
02a73c96 305 ($schema->source ('CD')->_mk_row_parser({
ce556881 306 inflate_map => $infmap,
307 collapse => 1,
ce556881 308 hri_style => 1,
79adc44f 309 prune_null_branches => 1,
02a73c96 310 }))[0],
aa1d8a87 311 ' my $rows_pos = 0;
312 my ($result_pos, @collapse_idx, $cur_row_data);
ce556881 313
314 while ($cur_row_data = (
3b4cd124 315 ( $rows_pos >= 0 and $_[0][$rows_pos++] )
ce556881 316 ||
3b4cd124 317 ( $_[1] and $rows_pos = -1 and $_[1]->() )
318 ) ) {
ce556881 319
ce556881 320 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
aa1d8a87 321 $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_data->[4]}{$cur_row_data->[5]} and (unshift @{$_[2]}, $cur_row_data) and last;
ce556881 322
323 # the rowdata itself for root node
cd784aab 324 $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] };
ce556881 325
326 # prefetch data of single_track (placed in root)
7596ddca 327 (! defined($cur_row_data->[1]) ) ? $collapse_idx[0]{$cur_row_data->[4]}{$cur_row_data->[5]}{single_track} = undef : do {
cd784aab 328 $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]};
ce556881 329
7596ddca 330 # prefetch data of cd (placed in single_track)
cd784aab 331 $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]};
ce556881 332
7596ddca 333 # prefetch data of artist ( placed in single_track->cd)
cd784aab 334 $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] };
ce556881 335
7596ddca 336 # prefetch data of cds (if available)
337 (! defined $cur_row_data->[3] ) ? $collapse_idx[3]{$cur_row_data->[1]}{$cur_row_data->[4]}{$cur_row_data->[5]}{cds} = [] : do {
ce556881 338
7596ddca 339 (! $collapse_idx[4]{$cur_row_data->[1]}{$cur_row_data->[3]}{$cur_row_data->[4]}{$cur_row_data->[5]} )
340 and
341 push @{$collapse_idx[3]{$cur_row_data->[1]}{$cur_row_data->[4]}{$cur_row_data->[5]}{cds}}, (
342 $collapse_idx[4]{$cur_row_data->[1]}{$cur_row_data->[3]}{$cur_row_data->[4]}{$cur_row_data->[5]} = { cdid => $cur_row_data->[3] }
343 );
ce556881 344
7596ddca 345 # prefetch data of tracks (if available)
346 ( ! 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 {
347
348 (! $collapse_idx[5]{$cur_row_data->[0]}{$cur_row_data->[1]}{$cur_row_data->[3]}{$cur_row_data->[4]}{$cur_row_data->[5]} )
349 and
350 push @{$collapse_idx[4]{$cur_row_data->[1]}{$cur_row_data->[3]}{$cur_row_data->[4]}{$cur_row_data->[5]}{tracks}}, (
351 $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] }
352 );
353 };
354 };
355 };
ce556881 356 }
aa1d8a87 357 $#{$_[0]} = $result_pos - 1;
ce556881 358 ',
52864fbd 359 'Same 1:1 descending terminating with chained 1:M:M but with collapse, HRI-direct',
ce556881 360);
361
4e9fc3f3 362$infmap = [qw/
3d8caf63 363 tracks.lyrics.existing_lyric_versions.text
4e9fc3f3 364 existing_single_track.cd.artist.artistid
365 existing_single_track.cd.artist.cds.year
366 year
367 genreid
368 tracks.title
369 existing_single_track.cd.artist.cds.cdid
370 latest_cd
371 existing_single_track.cd.artist.cds.tracks.title
372 existing_single_track.cd.artist.cds.genreid
3d8caf63 373 tracks.lyrics.existing_lyric_versions.lyric_id
4e9fc3f3 374/];
375
376is_deeply (
82f0e0aa 377 $schema->source('CD')->_resolve_collapse({ as => {map { $infmap->[$_] => $_ } 0 .. $#$infmap} }),
4e9fc3f3 378 {
9f98c4b2 379 -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid
4e9fc3f3 380
381 existing_single_track => {
9f98c4b2 382 -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid
4e9fc3f3 383 -is_single => 1,
384
385 cd => {
9f98c4b2 386 -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid
4e9fc3f3 387 -is_single => 1,
388
389 artist => {
9f98c4b2 390 -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid
4e9fc3f3 391 -is_single => 1,
392
393 cds => {
9f98c4b2 394 -identifying_columns => [ 1, 6 ], # existing_single_track.cd.artist.cds.cdid
4e9fc3f3 395 -is_optional => 1,
396
397 tracks => {
9f98c4b2 398 -identifying_columns => [ 1, 6, 8 ], # existing_single_track.cd.artist.cds.cdid, existing_single_track.cd.artist.cds.tracks.title
4e9fc3f3 399 -is_optional => 1,
400 }
401 }
402 }
403 }
404 },
405 tracks => {
9f98c4b2 406 -identifying_columns => [ 1, 5 ], # existing_single_track.cd.artist.artistid, tracks.title
4e9fc3f3 407 -is_optional => 1,
408
409 lyrics => {
3d8caf63 410 -identifying_columns => [ 1, 5, 10 ], # existing_single_track.cd.artist.artistid, tracks.title, tracks.lyrics.existing_lyric_versions.lyric_id
4e9fc3f3 411 -is_single => 1,
412 -is_optional => 1,
413
3d8caf63 414 existing_lyric_versions => {
415 -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
4e9fc3f3 416 },
417 },
418 }
419 },
420 'Correct collapse map constructed',
421);
422
423is_same_src (
02a73c96 424 ($schema->source ('CD')->_mk_row_parser({
4e9fc3f3 425 inflate_map => $infmap,
426 collapse => 1,
02a73c96 427 }))[0],
aa1d8a87 428 ' my $rows_pos = 0;
429 my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids);
4e9fc3f3 430
9f98c4b2 431 while ($cur_row_data = (
3b4cd124 432 ( $rows_pos >= 0 and $_[0][$rows_pos++] )
4e9fc3f3 433 ||
3b4cd124 434 ( $_[1] and $rows_pos = -1 and $_[1]->() )
435 ) ) {
4e9fc3f3 436
cd784aab 437 $cur_row_ids{0} = $cur_row_data->[0] // "\0NULL\xFF$rows_pos\xFF0\0";
438 $cur_row_ids{1} = $cur_row_data->[1] // "\0NULL\xFF$rows_pos\xFF1\0";
439 $cur_row_ids{5} = $cur_row_data->[5] // "\0NULL\xFF$rows_pos\xFF5\0";
440 $cur_row_ids{6} = $cur_row_data->[6] // "\0NULL\xFF$rows_pos\xFF6\0";
441 $cur_row_ids{8} = $cur_row_data->[8] // "\0NULL\xFF$rows_pos\xFF8\0";
442 $cur_row_ids{10} = $cur_row_data->[10] // "\0NULL\xFF$rows_pos\xFF10\0";
4e9fc3f3 443
9f98c4b2 444 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
aa1d8a87 445 $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{1}} and (unshift @{$_[2]}, $cur_row_data) and last;
4e9fc3f3 446
cd784aab 447 $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] }];
4e9fc3f3 448
cd784aab 449 $collapse_idx[0]{$cur_row_ids{1}}[1]{existing_single_track} //= $collapse_idx[1]{$cur_row_ids{1}} = [];
450 $collapse_idx[1]{$cur_row_ids{1}}[1]{cd} //= $collapse_idx[2]{$cur_row_ids{1}} = [];
451 $collapse_idx[2]{$cur_row_ids{1}}[1]{artist} //= $collapse_idx[3]{$cur_row_ids{1}} = [{ artistid => $cur_row_data->[1] }];
4e9fc3f3 452
ce556881 453 (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}} )
454 and
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] }]
457 );
52864fbd 458 defined($cur_row_data->[6]) or bless( $collapse_idx[3]{$cur_row_ids{1}}[1]{cds}, __NBC__ );
4e9fc3f3 459
ce556881 460 (! $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} )
461 and
462 push @{ $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} }, (
463 $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }]
464 );
52864fbd 465 defined($cur_row_data->[8]) or bless( $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks}, __NBC__ );
4e9fc3f3 466
ce556881 467 (! $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} )
468 and
469 push @{ $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} }, (
470 $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} = [{ title => $cur_row_data->[5] }]
471 );
52864fbd 472 defined($cur_row_data->[5]) or bless( $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks}, __NBC__ );
4e9fc3f3 473
cd784aab 474 $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}} = [];
52864fbd 475 defined($cur_row_data->[10]) or bless( $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}}[1]{lyrics}, __NBC__ );
4e9fc3f3 476
ce556881 477 (! $collapse_idx[8]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} )
478 and
479 push @{ $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}}[1]{existing_lyric_versions} }, (
480 $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] }]
481 );
4e9fc3f3 482 }
483
aa1d8a87 484 $#{$_[0]} = $result_pos - 1;
4e9fc3f3 485 ',
486 'Multiple has_many on multiple branches torture test',
487);
488
ce556881 489is_same_src (
02a73c96 490 ($schema->source ('CD')->_mk_row_parser({
ce556881 491 inflate_map => $infmap,
492 collapse => 1,
79adc44f 493 prune_null_branches => 1,
02a73c96 494 }))[0],
aa1d8a87 495 ' my $rows_pos = 0;
79adc44f 496 my ($result_pos, @collapse_idx, $cur_row_data);
ce556881 497
498 while ($cur_row_data = (
3b4cd124 499 ( $rows_pos >= 0 and $_[0][$rows_pos++] )
ce556881 500 ||
3b4cd124 501 ( $_[1] and $rows_pos = -1 and $_[1]->() )
502 ) ) {
ce556881 503
ce556881 504 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
79adc44f 505 $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_data->[1]} and (unshift @{$_[2]}, $cur_row_data) and last;
ce556881 506
cd784aab 507 $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] }];
ce556881 508
cd784aab 509 $collapse_idx[0]{$cur_row_data->[1]}[1]{existing_single_track} //= $collapse_idx[1]{$cur_row_data->[1]} = [];
510 $collapse_idx[1]{$cur_row_data->[1]}[1]{cd} //= $collapse_idx[2]{$cur_row_data->[1]} = [];
511 $collapse_idx[2]{$cur_row_data->[1]}[1]{artist} //= $collapse_idx[3]{$cur_row_data->[1]} = [{ artistid => $cur_row_data->[1] }];
ce556881 512
79adc44f 513 (! defined($cur_row_data->[6])) ? $collapse_idx[3]{$cur_row_data->[1]}[1]{cds} = [] : do {
514 (! $collapse_idx[4]{$cur_row_data->[1]}{$cur_row_data->[6]} )
515 and
516 push @{ $collapse_idx[3]{$cur_row_data->[1]}[1]{cds} }, (
517 $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] }]
518 );
ce556881 519
79adc44f 520 (! defined($cur_row_data->[8]) ) ? $collapse_idx[4]{$cur_row_data->[1]}{$cur_row_data->[6]}[1]{tracks} = [] : do {
ce556881 521
79adc44f 522 (! $collapse_idx[5]{$cur_row_data->[1]}{$cur_row_data->[6]}{$cur_row_data->[8]} )
523 and
524 push @{ $collapse_idx[4]{$cur_row_data->[1]}{$cur_row_data->[6]}[1]{tracks} }, (
525 $collapse_idx[5]{$cur_row_data->[1]}{$cur_row_data->[6]}{$cur_row_data->[8]} = [{ title => $cur_row_data->[8] }]
526 );
527 };
528 };
ce556881 529
79adc44f 530 (! defined($cur_row_data->[5]) ) ? $collapse_idx[0]{$cur_row_data->[1]}[1]{tracks} = [] : do {
ce556881 531
79adc44f 532 (! $collapse_idx[6]{$cur_row_data->[1]}{$cur_row_data->[5]} )
533 and
534 push @{ $collapse_idx[0]{$cur_row_data->[1]}[1]{tracks} }, (
535 $collapse_idx[6]{$cur_row_data->[1]}{$cur_row_data->[5]} = [{ title => $cur_row_data->[5] }]
536 );
537
538 (! defined($cur_row_data->[10]) ) ? $collapse_idx[6]{$cur_row_data->[1]}{$cur_row_data->[5]}[1]{lyrics} = [] : do {
539
cd784aab 540 $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]} = [];
79adc44f 541
542 (! $collapse_idx[8]{$cur_row_data->[0]}{$cur_row_data->[1]}{$cur_row_data->[5]}{$cur_row_data->[10]} )
543 and
544 push @{ $collapse_idx[7]{$cur_row_data->[1]}{$cur_row_data->[5]}{$cur_row_data->[10]}[1]{existing_lyric_versions} }, (
545 $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] }]
546 );
547 };
548 };
ce556881 549 }
550
aa1d8a87 551 $#{$_[0]} = $result_pos - 1;
ce556881 552 ',
79adc44f 553 'Multiple has_many on multiple branches with branch pruning torture test',
ce556881 554);
555
fcf32d04 556$infmap = [
557 'single_track.trackid', # (0) definitive link to root from 1:1:1:1:M:M chain
558 'year', # (1) non-unique
559 'tracks.cd', # (2) \ together both uniqueness for second multirel
560 'tracks.title', # (3) / and definitive link back to root
561 'single_track.cd.artist.cds.cdid', # (4) to give uniquiness to ...tracks.title below
562 'single_track.cd.artist.cds.year', # (5) non-unique
563 'single_track.cd.artist.artistid', # (6) uniqufies entire parental chain
564 'single_track.cd.artist.cds.genreid', # (7) nullable
565 'single_track.cd.artist.cds.tracks.title',# (8) unique when combined with ...cds.cdid above
566];
567
568is_deeply (
569 $schema->source('CD')->_resolve_collapse({ as => {map { $infmap->[$_] => $_ } 0 .. $#$infmap} }),
570 {
9f98c4b2 571 -identifying_columns => [],
572 -identifying_columns_variants => [
fcf32d04 573 [ 0 ], [ 2 ],
574 ],
575 single_track => {
9f98c4b2 576 -identifying_columns => [ 0 ],
fcf32d04 577 -is_optional => 1,
578 -is_single => 1,
fcf32d04 579 cd => {
9f98c4b2 580 -identifying_columns => [ 0 ],
fcf32d04 581 -is_single => 1,
fcf32d04 582 artist => {
9f98c4b2 583 -identifying_columns => [ 0 ],
fcf32d04 584 -is_single => 1,
fcf32d04 585 cds => {
9f98c4b2 586 -identifying_columns => [ 0, 4 ],
fcf32d04 587 -is_optional => 1,
fcf32d04 588 tracks => {
9f98c4b2 589 -identifying_columns => [ 0, 4, 8 ],
fcf32d04 590 -is_optional => 1,
fcf32d04 591 }
592 }
593 }
594 }
595 },
596 tracks => {
9f98c4b2 597 -identifying_columns => [ 2, 3 ],
fcf32d04 598 -is_optional => 1,
fcf32d04 599 }
600 },
601 'Correct underdefined root collapse map constructed'
602);
603
604is_same_src (
02a73c96 605 ($schema->source ('CD')->_mk_row_parser({
fcf32d04 606 inflate_map => $infmap,
607 collapse => 1,
02a73c96 608 }))[0],
aa1d8a87 609 ' my $rows_pos = 0;
610 my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids);
fcf32d04 611
9f98c4b2 612 while ($cur_row_data = (
3b4cd124 613 ( $rows_pos >= 0 and $_[0][$rows_pos++] )
fcf32d04 614 ||
3b4cd124 615 ( $_[1] and $rows_pos = -1 and $_[1]->() )
616 ) ) {
fcf32d04 617
cd784aab 618 $cur_row_ids{0} = $cur_row_data->[0] // "\0NULL\xFF$rows_pos\xFF0\0";
619 $cur_row_ids{2} = $cur_row_data->[2] // "\0NULL\xFF$rows_pos\xFF2\0";
620 $cur_row_ids{3} = $cur_row_data->[3] // "\0NULL\xFF$rows_pos\xFF3\0";
621 $cur_row_ids{4} = $cur_row_data->[4] // "\0NULL\xFF$rows_pos\xFF4\0";
622 $cur_row_ids{8} = $cur_row_data->[8] // "\0NULL\xFF$rows_pos\xFF8\0";
fcf32d04 623
624 # cache expensive set of ops in a non-existent rowid slot
9f98c4b2 625 $cur_row_ids{10} = (
626 ( ( defined $cur_row_data->[0] ) && (join "\xFF", q{}, $cur_row_data->[0], q{} ))
fcf32d04 627 or
9f98c4b2 628 ( ( defined $cur_row_data->[2] ) && (join "\xFF", q{}, $cur_row_data->[2], q{} ))
fcf32d04 629 or
630 "\0$rows_pos\0"
631 );
632
9f98c4b2 633 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
aa1d8a87 634 $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{10}} and (unshift @{$_[2]}, $cur_row_data) and last;
fcf32d04 635
cd784aab 636 $collapse_idx[0]{$cur_row_ids{10}} //= $_[0][$result_pos++] = [{ year => $$cur_row_data[1] }];
fcf32d04 637
cd784aab 638 $collapse_idx[0]{$cur_row_ids{10}}[1]{single_track} //= ($collapse_idx[1]{$cur_row_ids{0}} = [{ trackid => $cur_row_data->[0] }]);
52864fbd 639 defined($cur_row_data->[0]) or bless ( $collapse_idx[0]{$cur_row_ids{10}}[1]{single_track}, __NBC__ );
fcf32d04 640
cd784aab 641 $collapse_idx[1]{$cur_row_ids{0}}[1]{cd} //= $collapse_idx[2]{$cur_row_ids{0}} = [];
fcf32d04 642
cd784aab 643 $collapse_idx[2]{$cur_row_ids{0}}[1]{artist} //= ($collapse_idx[3]{$cur_row_ids{0}} = [{ artistid => $cur_row_data->[6] }]);
fcf32d04 644
ce556881 645 (! $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}} )
646 and
647 push @{$collapse_idx[3]{$cur_row_ids{0}}[1]{cds}}, (
52864fbd 648 $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] }]
ce556881 649 );
52864fbd 650 defined($cur_row_data->[4]) or bless ( $collapse_idx[3]{$cur_row_ids{0}}[1]{cds}, __NBC__ );
fcf32d04 651
ce556881 652 (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} )
653 and
654 push @{$collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}[1]{tracks}}, (
52864fbd 655 $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }]
ce556881 656 );
52864fbd 657 defined($cur_row_data->[8]) or bless ( $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}[1]{tracks}, __NBC__ );
fcf32d04 658
ce556881 659 (! $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} )
660 and
661 push @{$collapse_idx[0]{$cur_row_ids{10}}[1]{tracks}}, (
52864fbd 662 $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} = [{ cd => $$cur_row_data[2], title => $cur_row_data->[3] }]
ce556881 663 );
52864fbd 664 defined($cur_row_data->[2]) or bless ( $collapse_idx[0]{$cur_row_ids{10}}[1]{tracks}, __NBC__ );
fcf32d04 665 }
666
aa1d8a87 667 $#{$_[0]} = $result_pos - 1;
fcf32d04 668 ',
669 'Multiple has_many on multiple branches with underdefined root torture test',
670);
671
ce556881 672is_same_src (
02a73c96 673 ($schema->source ('CD')->_mk_row_parser({
ce556881 674 inflate_map => $infmap,
675 collapse => 1,
ce556881 676 hri_style => 1,
79adc44f 677 prune_null_branches => 1,
02a73c96 678 }))[0],
aa1d8a87 679 ' my $rows_pos = 0;
06b3406d 680 my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids);
ce556881 681
682 while ($cur_row_data = (
3b4cd124 683 ( $rows_pos >= 0 and $_[0][$rows_pos++] )
ce556881 684 ||
3b4cd124 685 ( $_[1] and $rows_pos = -1 and $_[1]->() )
686 ) ) {
687
5e6d06f4 688 # do not care about nullability here
689 $cur_row_ids{0} = $cur_row_data->[0];
690 $cur_row_ids{2} = $cur_row_data->[2];
691 $cur_row_ids{3} = $cur_row_data->[3];
692 $cur_row_ids{4} = $cur_row_data->[4];
693 $cur_row_ids{8} = $cur_row_data->[8];
06b3406d 694
ce556881 695 # cache expensive set of ops in a non-existent rowid slot
06b3406d 696 $cur_row_ids{10} = (
ce556881 697 ( ( defined $cur_row_data->[0] ) && (join "\xFF", q{}, $cur_row_data->[0], q{} ))
698 or
699 ( ( defined $cur_row_data->[2] ) && (join "\xFF", q{}, $cur_row_data->[2], q{} ))
700 or
701 "\0$rows_pos\0"
702 );
703
704 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
06b3406d 705 $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{10}} and (unshift @{$_[2]}, $cur_row_data) and last;
ce556881 706
cd784aab 707 $collapse_idx[0]{$cur_row_ids{10}} //= $_[0][$result_pos++] = { year => $$cur_row_data[1] };
ce556881 708
06b3406d 709 (! defined $cur_row_data->[0] ) ? $collapse_idx[0]{$cur_row_ids{10}}{single_track} = undef : do {
ce556881 710
cd784aab 711 $collapse_idx[0]{$cur_row_ids{10}}{single_track} //= ($collapse_idx[1]{$cur_row_ids{0}} = { trackid => $$cur_row_data[0] });
ce556881 712
cd784aab 713 $collapse_idx[1]{$cur_row_ids{0}}{cd} //= $collapse_idx[2]{$cur_row_ids{0}};
ce556881 714
cd784aab 715 $collapse_idx[2]{$cur_row_ids{0}}{artist} //= ($collapse_idx[3]{$cur_row_ids{0}} = { artistid => $$cur_row_data[6] });
ce556881 716
06b3406d 717 (! defined $cur_row_data->[4] ) ? $collapse_idx[3]{$cur_row_ids{0}}{cds} = [] : do {
ce556881 718
06b3406d 719 (! $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}} )
7596ddca 720 and
06b3406d 721 push @{$collapse_idx[3]{$cur_row_ids{0}}{cds}}, (
722 $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] }
7596ddca 723 );
ce556881 724
06b3406d 725 (! defined $cur_row_data->[8] ) ? $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}{tracks} = [] : do {
7596ddca 726
06b3406d 727 (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} )
7596ddca 728 and
06b3406d 729 push @{$collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}{tracks}}, (
730 $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} = { title => $$cur_row_data[8] }
7596ddca 731 );
732 };
733 };
734 };
735
06b3406d 736 (! defined $cur_row_data->[2] ) ? $collapse_idx[0]{$cur_row_ids{10}}{tracks} = [] : do {
737 (! $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} )
7596ddca 738 and
06b3406d 739 push @{$collapse_idx[0]{$cur_row_ids{10}}{tracks}}, (
740 $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} = { cd => $$cur_row_data[2], title => $$cur_row_data[3] }
7596ddca 741 );
742 };
ce556881 743 }
744
aa1d8a87 745 $#{$_[0]} = $result_pos - 1;
ce556881 746 ',
52864fbd 747 'Multiple has_many on multiple branches with underdefined root, HRI-direct torture test',
ce556881 748);
749
4e9fc3f3 750done_testing;
751
752my $deparser;
cd784aab 753sub is_same_src { SKIP: {
2fdeef65 754
755 skip "Skipping comparison of unicode-posioned source", 1
756 if DBIx::Class::_ENV_::STRESSTEST_UTF8_UPGRADE_GENERATED_COLLAPSER_SOURCE;
757
4e9fc3f3 758 $deparser ||= B::Deparse->new;
759 local $Test::Builder::Level = $Test::Builder::Level + 1;
760
52864fbd 761 my ($got, $expect) = @_;
762
cd784aab 763 skip "Not testing equality of source containing defined-or operator on this perl $]", 1
764 if ($] < 5.010 and$expect =~ m!\Q//=!);
765
01b25f12 766 $expect =~ s/__NBC__/perlstring($DBIx::Class::ResultSource::RowParser::Util::null_branch_class)/ge;
52864fbd 767
9f7d5590 768 $expect = " { use strict; use warnings FATAL => 'uninitialized';\n$expect\n }";
bdbd2ae8 769
52864fbd 770 my @normalized = map {
4e9fc3f3 771 my $cref = eval "sub { $_ }" or do {
772 fail "Coderef does not compile!\n\n$@\n\n$_";
773 return undef;
774 };
775 $deparser->coderef2text($cref);
52864fbd 776 } ($got, $expect);
777
778 &is (@normalized, $_[2]||() ) or do {
779 eval { require Test::Differences }
780 ? &Test::Differences::eq_or_diff( @normalized, $_[2]||() )
e81b50f4 781 : note ("Original sources:\n\n$got\n\n$expect\n")
782 ;
783 exit 1;
52864fbd 784 };
cd784aab 785} }