Support one more convoluted case of data-poor collapse
[dbsrgits/DBIx-Class.git] / t / resultset / rowparser_internals.t
CommitLineData
c0329273 1BEGIN { do "./t/lib/ANFANG.pm" or die ( $@ || $! ) }
2
4e9fc3f3 3use strict;
4use warnings;
5
6use Test::More;
c0329273 7
4e9fc3f3 8use DBICTest;
9use B::Deparse;
01b25f12 10use DBIx::Class::_Util 'perlstring';
4e9fc3f3 11
12my $schema = DBICTest->init_schema(no_deploy => 1);
ce556881 13my $infmap = [qw/
14 single_track.cd.artist.name
15 year
16/];
4e9fc3f3 17
18is_same_src (
02a73c96 19 ($schema->source ('CD')->_mk_row_parser({
4e9fc3f3 20 inflate_map => $infmap,
02a73c96 21 }))[0],
4e9fc3f3 22 '$_ = [
23 { year => $_->[1] },
52864fbd 24 { single_track => ( ! defined( $_->[0]) )
25 ? bless( [
4e9fc3f3 26 undef,
52864fbd 27 { cd => [
28 undef,
29 { artist => [
30 { name => $_->[0] },
31 ] },
4e9fc3f3 32 ] },
52864fbd 33 ], __NBC__ )
34 : [
35 undef,
36 { cd => [
37 undef,
38 { artist => [
39 { name => $_->[0] },
40 ] },
41 ] },
42 ]
43 },
4e9fc3f3 44 ] for @{$_[0]}',
45 'Simple 1:1 descending non-collapsing parser',
46);
47
48$infmap = [qw/
3faac878 49 single_track.cd.artist.cds.tracks.title
4e9fc3f3 50 single_track.cd.artist.artistid
51 year
4e9fc3f3 52 single_track.cd.artist.cds.cdid
53 title
54 artist
55/];
4e9fc3f3 56
ce556881 57is_same_src (
02a73c96 58 ($schema->source ('CD')->_mk_row_parser({
ce556881 59 inflate_map => $infmap,
02a73c96 60 }))[0],
ce556881 61 '$_ = [
62 { artist => $_->[5], title => $_->[4], year => $_->[2] },
63 {
52864fbd 64 single_track => ( (! defined $_->[0] ) && (! defined $_->[1]) && (! defined $_->[3] ) )
65 ? bless( [
66 undef,
67 {
68 cd => [
69 undef,
70 {
71 artist => [
72 { artistid => $_->[1] },
73 {
74 cds => ( (! defined $_->[0] ) && ( ! defined $_->[3] ) )
75 ? bless ([
76 { cdid => $_->[3] },
77 {
78 tracks => ( ! defined $_->[0] )
79 ? bless ( [{ title => $_->[0] }], __NBC__ )
80 : [{ title => $_->[0] }]
81 }
82 ], __NBC__)
83 : [
84 { cdid => $_->[3] },
85 {
86 tracks => ( ! defined $_->[0] )
87 ? bless ( [{ title => $_->[0] }], __NBC__ )
88 : [{ title => $_->[0] }]
89 }
90 ]
91 }
92 ]
93 }
94 ]
95 }
96 ], __NBC__)
97 : [
ce556881 98 undef,
99 {
100 cd => [
101 undef,
102 {
103 artist => [
104 { artistid => $_->[1] },
105 {
52864fbd 106 cds => ( (! defined $_->[0] ) && ( ! defined $_->[3] ) )
107 ? bless ([
108 { cdid => $_->[3] },
109 {
110 tracks => ( ! defined $_->[0] )
111 ? bless ( [{ title => $_->[0] }], __NBC__ )
112 : [{ title => $_->[0] }]
113 }
114 ], __NBC__)
115 : [
ce556881 116 { cdid => $_->[3] },
117 {
52864fbd 118 tracks => ( ! defined $_->[0] )
119 ? bless ( [{ title => $_->[0] }], __NBC__ )
120 : [{ title => $_->[0] }]
ce556881 121 }
52864fbd 122 ]
ce556881 123 }
124 ]
125 }
126 ]
127 }
52864fbd 128 ]
ce556881 129 }
130 ] for @{$_[0]}',
52864fbd 131 '1:1 descending non-collapsing parser terminating with chained 1:M:M',
ce556881 132);
133
134is_same_src (
02a73c96 135 ($schema->source ('CD')->_mk_row_parser({
79adc44f 136 prune_null_branches => 1,
137 inflate_map => $infmap,
02a73c96 138 }))[0],
79adc44f 139 '$_ = [
140 { artist => $_->[5], title => $_->[4], year => $_->[2] },
141 {
142 single_track => ( (! defined $_->[0] ) && (! defined $_->[1]) && (! defined $_->[3] ) ) ? undef : [
143 undef,
144 {
145 cd => [
146 undef,
147 {
148 artist => [
149 { artistid => $_->[1] },
150 {
151 cds => ( (! defined $_->[0] ) && ( ! defined $_->[3] ) ) ? undef : [
152 { cdid => $_->[3] },
153 {
154 tracks => ( ! defined $_->[0] ) ? undef : [
155 { title => $_->[0] },
156 ]
157 }
158 ]
159 }
160 ]
161 }
162 ]
163 }
164 ]
165 }
166 ] for @{$_[0]}',
167 '1:1 descending non-collapsing pruning parser terminating with chained 1:M:M',
168);
169
170is_same_src (
02a73c96 171 ($schema->source ('CD')->_mk_row_parser({
ce556881 172 hri_style => 1,
79adc44f 173 prune_null_branches => 1,
ce556881 174 inflate_map => $infmap,
02a73c96 175 }))[0],
ce556881 176 '$_ = {
177 artist => $_->[5], title => $_->[4], year => $_->[2],
178
52864fbd 179 ( single_track => ( (! defined $_->[0] ) && (! defined $_->[1]) && (! defined $_->[3] ) )
180 ? undef
181 : {
ce556881 182 cd =>
183 {
184 artist => {
185 artistid => $_->[1],
52864fbd 186 ( cds => ( (! defined $_->[0] ) && ( ! defined $_->[3] ) )
187 ? undef
188 : {
ce556881 189 cdid => $_->[3],
52864fbd 190 ( tracks => ( ! defined $_->[0] )
191 ? undef
192 : { title => $_->[0] }
193 )
ce556881 194 }
52864fbd 195 )
ce556881 196 }
197 }
198 }
52864fbd 199 )
ce556881 200 } for @{$_[0]}',
52864fbd 201 '1:1 descending non-collapsing HRI-direct parser terminating with chained 1:M:M',
ce556881 202);
203
204
205
4e9fc3f3 206is_deeply (
3faac878 207 ($schema->source('CD')->_resolve_collapse({ as => {map { $infmap->[$_] => $_ } 0 .. $#$infmap} })),
4e9fc3f3 208 {
9f98c4b2 209 -identifying_columns => [ 4, 5 ],
4e9fc3f3 210
211 single_track => {
a0726a33 212 -identifying_columns => [ 1, 4, 5 ],
4e9fc3f3 213 -is_optional => 1,
214 -is_single => 1,
215
216 cd => {
a0726a33 217 -identifying_columns => [ 1, 4, 5 ],
4e9fc3f3 218 -is_single => 1,
219
220 artist => {
a0726a33 221 -identifying_columns => [ 1, 4, 5 ],
4e9fc3f3 222 -is_single => 1,
223
224 cds => {
a0726a33 225 -identifying_columns => [ 1, 3, 4, 5 ],
4e9fc3f3 226 -is_optional => 1,
227
228 tracks => {
a0726a33 229 -identifying_columns => [ 0, 1, 3, 4, 5 ],
4e9fc3f3 230 -is_optional => 1,
231 },
232 },
233 },
234 },
235 },
236 },
237 'Correct collapse map for 1:1 descending chain terminating with chained 1:M:M'
238);
239
240is_same_src (
02a73c96 241 ($schema->source ('CD')->_mk_row_parser({
4e9fc3f3 242 inflate_map => $infmap,
243 collapse => 1,
02a73c96 244 }))[0],
aa1d8a87 245 ' my $rows_pos = 0;
246 my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids);
4e9fc3f3 247
9f98c4b2 248 while ($cur_row_data = (
164aab8c 249 (
250 $rows_pos >= 0
251 and
252 (
253 $_[0][$rows_pos++]
254 or
255 ( ($rows_pos = -1), undef )
256 )
257 )
258 or
259 ( $_[1] and $_[1]->() )
3b4cd124 260 ) ) {
4e9fc3f3 261
05a5ca4b 262 ( @cur_row_ids{0,1,3,4,5} = (
c863e102 263 ( $cur_row_data->[0] // "\0NULL\xFF$rows_pos\xFF0\0" ),
264 ( $cur_row_data->[1] // "\0NULL\xFF$rows_pos\xFF1\0" ),
265 ( $cur_row_data->[3] // "\0NULL\xFF$rows_pos\xFF3\0" ),
266 ( $cur_row_data->[4] // "\0NULL\xFF$rows_pos\xFF4\0" ),
267 ( $cur_row_data->[5] // "\0NULL\xFF$rows_pos\xFF5\0" ),
05a5ca4b 268 ) ),
4e9fc3f3 269
3faac878 270 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
05a5ca4b 271 ( $_[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 272
3faac878 273 # the rowdata itself for root node
05a5ca4b 274 ( $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 275
276 # prefetch data of single_track (placed in root)
05a5ca4b 277 ( $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}} = [] ),
278 ( defined($cur_row_data->[1]) or bless( $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{single_track}, __NBC__ ) ),
3faac878 279
280 # prefetch data of cd (placed in single_track)
05a5ca4b 281 ( $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 282
3faac878 283 # prefetch data of artist ( placed in single_track->cd)
05a5ca4b 284 ( $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 285
286 # prefetch data of cds (if available)
05a5ca4b 287 (
288 (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} )
289 and
290 push @{$collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{cds}}, (
291 $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} = [{ cdid => $cur_row_data->[3] }]
292 )
293 ),
294 ( 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 295
3faac878 296 # prefetch data of tracks (if available)
05a5ca4b 297 (
298 (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} )
299 and
300 push @{$collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{tracks}}, (
301 $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] }]
302 )
303 ),
304 ( 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 305
4e9fc3f3 306 }
aa1d8a87 307 $#{$_[0]} = $result_pos - 1;
4e9fc3f3 308 ',
309 'Same 1:1 descending terminating with chained 1:M:M but with collapse',
310);
311
ce556881 312is_same_src (
02a73c96 313 ($schema->source ('CD')->_mk_row_parser({
ce556881 314 inflate_map => $infmap,
315 collapse => 1,
ce556881 316 hri_style => 1,
79adc44f 317 prune_null_branches => 1,
02a73c96 318 }))[0],
aa1d8a87 319 ' my $rows_pos = 0;
c863e102 320 my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids);
ce556881 321
322 while ($cur_row_data = (
164aab8c 323 (
324 $rows_pos >= 0
325 and
326 (
327 $_[0][$rows_pos++]
328 or
329 ( ($rows_pos = -1), undef )
330 )
331 )
332 or
333 ( $_[1] and $_[1]->() )
3b4cd124 334 ) ) {
ce556881 335
05a5ca4b 336 ( @cur_row_ids{0, 1, 3, 4, 5} = @{$cur_row_data}[0, 1, 3, 4, 5] ),
c863e102 337
ce556881 338 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
05a5ca4b 339 ( $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}} and (unshift @{$_[2]}, $cur_row_data) and last ),
ce556881 340
341 # the rowdata itself for root node
05a5ca4b 342 ( $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] } ),
ce556881 343
344 # prefetch data of single_track (placed in root)
05a5ca4b 345 ( (! defined($cur_row_data->[1]) ) ? $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}}{single_track} = undef : do {
40471d46 346 ( $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}} = {} ),
ce556881 347
7596ddca 348 # prefetch data of cd (placed in single_track)
40471d46 349 ( $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}} = {} ),
ce556881 350
7596ddca 351 # prefetch data of artist ( placed in single_track->cd)
05a5ca4b 352 ( $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] } ),
ce556881 353
7596ddca 354 # prefetch data of cds (if available)
05a5ca4b 355 ( (! defined $cur_row_data->[3] ) ? $collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}{cds} = [] : do {
ce556881 356
05a5ca4b 357 (
358 (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} )
359 and
360 push @{$collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}{cds}}, (
361 $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} = { cdid => $cur_row_data->[3] }
362 )
363 ),
ce556881 364
7596ddca 365 # prefetch data of tracks (if available)
05a5ca4b 366 (( ! 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 {
367
368 (
369 (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} )
370 and
371 push @{$collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}}{tracks}}, (
372 $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] }
373 )
374 ),
375 } ),
376 } ),
377 } ),
ce556881 378 }
aa1d8a87 379 $#{$_[0]} = $result_pos - 1;
ce556881 380 ',
52864fbd 381 'Same 1:1 descending terminating with chained 1:M:M but with collapse, HRI-direct',
ce556881 382);
383
4e9fc3f3 384$infmap = [qw/
3d8caf63 385 tracks.lyrics.existing_lyric_versions.text
4e9fc3f3 386 existing_single_track.cd.artist.artistid
387 existing_single_track.cd.artist.cds.year
388 year
389 genreid
390 tracks.title
391 existing_single_track.cd.artist.cds.cdid
392 latest_cd
393 existing_single_track.cd.artist.cds.tracks.title
394 existing_single_track.cd.artist.cds.genreid
3d8caf63 395 tracks.lyrics.existing_lyric_versions.lyric_id
4e9fc3f3 396/];
397
398is_deeply (
82f0e0aa 399 $schema->source('CD')->_resolve_collapse({ as => {map { $infmap->[$_] => $_ } 0 .. $#$infmap} }),
4e9fc3f3 400 {
9f98c4b2 401 -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid
4e9fc3f3 402
403 existing_single_track => {
9f98c4b2 404 -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid
4e9fc3f3 405 -is_single => 1,
406
407 cd => {
9f98c4b2 408 -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid
4e9fc3f3 409 -is_single => 1,
410
411 artist => {
9f98c4b2 412 -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid
4e9fc3f3 413 -is_single => 1,
414
415 cds => {
9f98c4b2 416 -identifying_columns => [ 1, 6 ], # existing_single_track.cd.artist.cds.cdid
4e9fc3f3 417 -is_optional => 1,
418
419 tracks => {
9f98c4b2 420 -identifying_columns => [ 1, 6, 8 ], # existing_single_track.cd.artist.cds.cdid, existing_single_track.cd.artist.cds.tracks.title
4e9fc3f3 421 -is_optional => 1,
422 }
423 }
424 }
425 }
426 },
427 tracks => {
9f98c4b2 428 -identifying_columns => [ 1, 5 ], # existing_single_track.cd.artist.artistid, tracks.title
4e9fc3f3 429 -is_optional => 1,
430
431 lyrics => {
3d8caf63 432 -identifying_columns => [ 1, 5, 10 ], # existing_single_track.cd.artist.artistid, tracks.title, tracks.lyrics.existing_lyric_versions.lyric_id
4e9fc3f3 433 -is_single => 1,
434 -is_optional => 1,
435
3d8caf63 436 existing_lyric_versions => {
437 -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 438 },
439 },
440 }
441 },
442 'Correct collapse map constructed',
443);
444
445is_same_src (
02a73c96 446 ($schema->source ('CD')->_mk_row_parser({
4e9fc3f3 447 inflate_map => $infmap,
448 collapse => 1,
02a73c96 449 }))[0],
aa1d8a87 450 ' my $rows_pos = 0;
451 my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids);
4e9fc3f3 452
9f98c4b2 453 while ($cur_row_data = (
164aab8c 454 (
455 $rows_pos >= 0
456 and
457 (
458 $_[0][$rows_pos++]
459 or
460 ( ($rows_pos = -1), undef )
461 )
462 )
463 or
464 ( $_[1] and $_[1]->() )
3b4cd124 465 ) ) {
4e9fc3f3 466
05a5ca4b 467 ( @cur_row_ids{0, 1, 5, 6, 8, 10} = (
c863e102 468 $cur_row_data->[0] // "\0NULL\xFF$rows_pos\xFF0\0",
469 $cur_row_data->[1] // "\0NULL\xFF$rows_pos\xFF1\0",
470 $cur_row_data->[5] // "\0NULL\xFF$rows_pos\xFF5\0",
471 $cur_row_data->[6] // "\0NULL\xFF$rows_pos\xFF6\0",
472 $cur_row_data->[8] // "\0NULL\xFF$rows_pos\xFF8\0",
473 $cur_row_data->[10] // "\0NULL\xFF$rows_pos\xFF10\0",
05a5ca4b 474 ) ),
4e9fc3f3 475
9f98c4b2 476 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
05a5ca4b 477 ( $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{1}} and (unshift @{$_[2]}, $cur_row_data) and last ),
478
479 ( $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] }] ),
480
481 ( $collapse_idx[0]{$cur_row_ids{1}}[1]{existing_single_track} //= $collapse_idx[1]{$cur_row_ids{1}} = [] ),
482 ( $collapse_idx[1]{$cur_row_ids{1}}[1]{cd} //= $collapse_idx[2]{$cur_row_ids{1}} = [] ),
483 ( $collapse_idx[2]{$cur_row_ids{1}}[1]{artist} //= $collapse_idx[3]{$cur_row_ids{1}} = [{ artistid => $cur_row_data->[1] }] ),
484
485 (
486 (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}} )
487 and
488 push @{ $collapse_idx[3]{$cur_row_ids{1}}[1]{cds} }, (
489 $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] }]
490 )
491 ),
492 ( defined($cur_row_data->[6]) or bless( $collapse_idx[3]{$cur_row_ids{1}}[1]{cds}, __NBC__ ) ),
493
494 (
495 (! $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} )
496 and
497 push @{ $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} }, (
498 $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }]
499 )
500 ),
501 ( defined($cur_row_data->[8]) or bless( $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks}, __NBC__ ) ),
502
503 (
504 (! $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} )
505 and
506 push @{ $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} }, (
507 $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} = [{ title => $cur_row_data->[5] }]
508 )
509 ),
510 ( defined($cur_row_data->[5]) or bless( $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks}, __NBC__ ) ),
511
512 ( $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}} = [] ),
513 ( defined($cur_row_data->[10]) or bless( $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}}[1]{lyrics}, __NBC__ ) ),
514
515 (
516 (! $collapse_idx[8]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} )
517 and
518 push @{ $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}}[1]{existing_lyric_versions} }, (
519 $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] }]
520 )
521 ),
4e9fc3f3 522 }
523
aa1d8a87 524 $#{$_[0]} = $result_pos - 1;
4e9fc3f3 525 ',
526 'Multiple has_many on multiple branches torture test',
527);
528
ce556881 529is_same_src (
02a73c96 530 ($schema->source ('CD')->_mk_row_parser({
ce556881 531 inflate_map => $infmap,
532 collapse => 1,
79adc44f 533 prune_null_branches => 1,
02a73c96 534 }))[0],
aa1d8a87 535 ' my $rows_pos = 0;
c863e102 536 my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids);
ce556881 537
538 while ($cur_row_data = (
164aab8c 539 (
540 $rows_pos >= 0
541 and
542 (
543 $_[0][$rows_pos++]
544 or
545 ( ($rows_pos = -1), undef )
546 )
547 )
548 or
549 ( $_[1] and $_[1]->() )
3b4cd124 550 ) ) {
ce556881 551
05a5ca4b 552 ( @cur_row_ids{( 0, 1, 5, 6, 8, 10 )} = @{$cur_row_data}[( 0, 1, 5, 6, 8, 10 )] ),
c863e102 553
ce556881 554 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
05a5ca4b 555 ( $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{1}} and (unshift @{$_[2]}, $cur_row_data) and last ),
ce556881 556
05a5ca4b 557 ( $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] }] ),
ce556881 558
05a5ca4b 559 ( $collapse_idx[0]{$cur_row_ids{1}}[1]{existing_single_track} //= $collapse_idx[1]{$cur_row_ids{1}} = [] ),
560 ( $collapse_idx[1]{$cur_row_ids{1}}[1]{cd} //= $collapse_idx[2]{$cur_row_ids{1}} = [] ),
561 ( $collapse_idx[2]{$cur_row_ids{1}}[1]{artist} //= $collapse_idx[3]{$cur_row_ids{1}} = [{ artistid => $cur_row_data->[1] }] ),
ce556881 562
05a5ca4b 563 ( (! defined($cur_row_data->[6])) ? $collapse_idx[3]{$cur_row_ids{1}}[1]{cds} = [] : do {
564 (
565 (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}} )
79adc44f 566 and
05a5ca4b 567 push @{ $collapse_idx[3]{$cur_row_ids{1}}[1]{cds} }, (
568 $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] }]
569 )
570 ),
571
572 ( (! defined($cur_row_data->[8]) ) ? $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} = [] : do {
573 (
574 (! $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} )
575 and
576 push @{ $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} }, (
577 $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }]
578 )
579 ),
580 } ),
581 } ),
ce556881 582
05a5ca4b 583 ( (! defined($cur_row_data->[5]) ) ? $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} = [] : do {
ce556881 584
05a5ca4b 585 (
586 (! $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} )
587 and
588 push @{ $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} }, (
589 $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} = [{ title => $cur_row_data->[5] }]
590 )
591 ),
79adc44f 592
05a5ca4b 593 ( (! defined($cur_row_data->[10]) ) ? $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}}[1]{lyrics} = [] : do {
79adc44f 594
05a5ca4b 595 ( $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}} = [] ),
79adc44f 596
05a5ca4b 597 (
598 (! $collapse_idx[8]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} )
599 and
600 push @{ $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}}[1]{existing_lyric_versions} }, (
601 $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] }]
602 )
603 ),
604 } ),
605 } ),
ce556881 606 }
607
aa1d8a87 608 $#{$_[0]} = $result_pos - 1;
ce556881 609 ',
79adc44f 610 'Multiple has_many on multiple branches with branch pruning torture test',
ce556881 611);
612
fcf32d04 613$infmap = [
614 'single_track.trackid', # (0) definitive link to root from 1:1:1:1:M:M chain
615 'year', # (1) non-unique
616 'tracks.cd', # (2) \ together both uniqueness for second multirel
617 'tracks.title', # (3) / and definitive link back to root
618 'single_track.cd.artist.cds.cdid', # (4) to give uniquiness to ...tracks.title below
619 'single_track.cd.artist.cds.year', # (5) non-unique
620 'single_track.cd.artist.artistid', # (6) uniqufies entire parental chain
621 'single_track.cd.artist.cds.genreid', # (7) nullable
622 'single_track.cd.artist.cds.tracks.title',# (8) unique when combined with ...cds.cdid above
623];
624
625is_deeply (
626 $schema->source('CD')->_resolve_collapse({ as => {map { $infmap->[$_] => $_ } 0 .. $#$infmap} }),
627 {
9f98c4b2 628 -identifying_columns => [],
629 -identifying_columns_variants => [
fcf32d04 630 [ 0 ], [ 2 ],
631 ],
632 single_track => {
9f98c4b2 633 -identifying_columns => [ 0 ],
fcf32d04 634 -is_optional => 1,
635 -is_single => 1,
fcf32d04 636 cd => {
9f98c4b2 637 -identifying_columns => [ 0 ],
fcf32d04 638 -is_single => 1,
fcf32d04 639 artist => {
9f98c4b2 640 -identifying_columns => [ 0 ],
fcf32d04 641 -is_single => 1,
fcf32d04 642 cds => {
9f98c4b2 643 -identifying_columns => [ 0, 4 ],
fcf32d04 644 -is_optional => 1,
fcf32d04 645 tracks => {
9f98c4b2 646 -identifying_columns => [ 0, 4, 8 ],
fcf32d04 647 -is_optional => 1,
fcf32d04 648 }
649 }
650 }
651 }
652 },
653 tracks => {
9f98c4b2 654 -identifying_columns => [ 2, 3 ],
fcf32d04 655 -is_optional => 1,
fcf32d04 656 }
657 },
658 'Correct underdefined root collapse map constructed'
659);
660
661is_same_src (
02a73c96 662 ($schema->source ('CD')->_mk_row_parser({
fcf32d04 663 inflate_map => $infmap,
664 collapse => 1,
02a73c96 665 }))[0],
aa1d8a87 666 ' my $rows_pos = 0;
667 my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids);
fcf32d04 668
9f98c4b2 669 while ($cur_row_data = (
164aab8c 670 (
671 $rows_pos >= 0
672 and
673 (
674 $_[0][$rows_pos++]
675 or
676 ( ($rows_pos = -1), undef )
677 )
678 )
679 or
680 ( $_[1] and $_[1]->() )
3b4cd124 681 ) ) {
fcf32d04 682
05a5ca4b 683 ( @cur_row_ids{( 0, 2, 3, 4, 8 )} = (
c863e102 684 $cur_row_data->[0] // "\0NULL\xFF$rows_pos\xFF0\0",
685 $cur_row_data->[2] // "\0NULL\xFF$rows_pos\xFF2\0",
686 $cur_row_data->[3] // "\0NULL\xFF$rows_pos\xFF3\0",
687 $cur_row_data->[4] // "\0NULL\xFF$rows_pos\xFF4\0",
688 $cur_row_data->[8] // "\0NULL\xFF$rows_pos\xFF8\0",
05a5ca4b 689 )),
fcf32d04 690
691 # cache expensive set of ops in a non-existent rowid slot
05a5ca4b 692 ( $cur_row_ids{10} = (
c863e102 693 ( ( defined $cur_row_data->[0] ) && (join "\xFF", q{}, $cur_row_ids{0}, q{} ))
fcf32d04 694 or
c863e102 695 ( ( defined $cur_row_data->[2] ) && (join "\xFF", q{}, $cur_row_ids{2}, q{} ))
fcf32d04 696 or
697 "\0$rows_pos\0"
05a5ca4b 698 )),
fcf32d04 699
9f98c4b2 700 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
05a5ca4b 701 ( $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{10}} and (unshift @{$_[2]}, $cur_row_data) and last ),
fcf32d04 702
05a5ca4b 703 ( $collapse_idx[0]{$cur_row_ids{10}} //= $_[0][$result_pos++] = [{ year => $$cur_row_data[1] }] ),
fcf32d04 704
05a5ca4b 705 ( $collapse_idx[0]{$cur_row_ids{10}}[1]{single_track} //= ($collapse_idx[1]{$cur_row_ids{0}} = [{ trackid => $cur_row_data->[0] }]) ),
706 ( defined($cur_row_data->[0]) or bless ( $collapse_idx[0]{$cur_row_ids{10}}[1]{single_track}, __NBC__ ) ),
fcf32d04 707
05a5ca4b 708 ( $collapse_idx[1]{$cur_row_ids{0}}[1]{cd} //= $collapse_idx[2]{$cur_row_ids{0}} = [] ),
fcf32d04 709
05a5ca4b 710 ( $collapse_idx[2]{$cur_row_ids{0}}[1]{artist} //= ($collapse_idx[3]{$cur_row_ids{0}} = [{ artistid => $cur_row_data->[6] }]) ),
fcf32d04 711
05a5ca4b 712 (
713 (! $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}} )
714 and
715 push @{$collapse_idx[3]{$cur_row_ids{0}}[1]{cds}}, (
52864fbd 716 $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] }]
05a5ca4b 717 )
718 ),
719 ( defined($cur_row_data->[4]) or bless ( $collapse_idx[3]{$cur_row_ids{0}}[1]{cds}, __NBC__ ) ),
720
721 (
722 (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} )
723 and
724 push @{$collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}[1]{tracks}}, (
725 $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }]
726 )
727 ),
728 ( defined($cur_row_data->[8]) or bless ( $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}[1]{tracks}, __NBC__ ) ),
729
730 (
731 (! $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} )
732 and
733 push @{$collapse_idx[0]{$cur_row_ids{10}}[1]{tracks}}, (
52864fbd 734 $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} = [{ cd => $$cur_row_data[2], title => $cur_row_data->[3] }]
05a5ca4b 735 )
736 ),
737 ( defined($cur_row_data->[2]) or bless ( $collapse_idx[0]{$cur_row_ids{10}}[1]{tracks}, __NBC__ ) ),
fcf32d04 738 }
739
aa1d8a87 740 $#{$_[0]} = $result_pos - 1;
fcf32d04 741 ',
742 'Multiple has_many on multiple branches with underdefined root torture test',
743);
744
ce556881 745is_same_src (
02a73c96 746 ($schema->source ('CD')->_mk_row_parser({
ce556881 747 inflate_map => $infmap,
748 collapse => 1,
ce556881 749 hri_style => 1,
79adc44f 750 prune_null_branches => 1,
02a73c96 751 }))[0],
aa1d8a87 752 ' my $rows_pos = 0;
06b3406d 753 my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids);
ce556881 754
755 while ($cur_row_data = (
164aab8c 756 (
757 $rows_pos >= 0
758 and
759 (
760 $_[0][$rows_pos++]
761 or
762 ( ($rows_pos = -1), undef )
763 )
764 )
765 or
766 ( $_[1] and $_[1]->() )
3b4cd124 767 ) ) {
768
5e6d06f4 769 # do not care about nullability here
05a5ca4b 770 ( @cur_row_ids{( 0, 2, 3, 4, 8 )} = @{$cur_row_data}[( 0, 2, 3, 4, 8 )] ),
06b3406d 771
ce556881 772 # cache expensive set of ops in a non-existent rowid slot
05a5ca4b 773 ( $cur_row_ids{10} = (
c863e102 774 ( ( defined $cur_row_data->[0] ) && (join "\xFF", q{}, $cur_row_ids{0}, q{} ))
ce556881 775 or
c863e102 776 ( ( defined $cur_row_data->[2] ) && (join "\xFF", q{}, $cur_row_ids{2}, q{} ))
ce556881 777 or
778 "\0$rows_pos\0"
05a5ca4b 779 )),
ce556881 780
781 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
05a5ca4b 782 ( $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{10}} and (unshift @{$_[2]}, $cur_row_data) and last ),
ce556881 783
05a5ca4b 784 ( $collapse_idx[0]{$cur_row_ids{10}} //= $_[0][$result_pos++] = { year => $$cur_row_data[1] } ),
ce556881 785
05a5ca4b 786 ( (! defined $cur_row_data->[0] ) ? $collapse_idx[0]{$cur_row_ids{10}}{single_track} = undef : do {
ce556881 787
05a5ca4b 788 ( $collapse_idx[0]{$cur_row_ids{10}}{single_track} //= ($collapse_idx[1]{$cur_row_ids{0}} = { trackid => $$cur_row_data[0] }) ),
ce556881 789
40471d46 790 ( $collapse_idx[1]{$cur_row_ids{0}}{cd} //= $collapse_idx[2]{$cur_row_ids{0}} = {} ),
ce556881 791
05a5ca4b 792 ( $collapse_idx[2]{$cur_row_ids{0}}{artist} //= ($collapse_idx[3]{$cur_row_ids{0}} = { artistid => $$cur_row_data[6] }) ),
ce556881 793
05a5ca4b 794 ( (! defined $cur_row_data->[4] ) ? $collapse_idx[3]{$cur_row_ids{0}}{cds} = [] : do {
ce556881 795
05a5ca4b 796 (
797 (! $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}} )
798 and
799 push @{$collapse_idx[3]{$cur_row_ids{0}}{cds}}, (
800 $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] }
801 )
802 ),
ce556881 803
05a5ca4b 804 ( (! defined $cur_row_data->[8] ) ? $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}{tracks} = [] : do {
7596ddca 805
06b3406d 806 (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} )
7596ddca 807 and
06b3406d 808 push @{$collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}{tracks}}, (
809 $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} = { title => $$cur_row_data[8] }
05a5ca4b 810 ),
811 } ),
812 } ),
813 } ),
7596ddca 814
05a5ca4b 815 ( (! defined $cur_row_data->[2] ) ? $collapse_idx[0]{$cur_row_ids{10}}{tracks} = [] : do {
816 (
817 (! $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} )
818 and
819 push @{$collapse_idx[0]{$cur_row_ids{10}}{tracks}}, (
06b3406d 820 $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} = { cd => $$cur_row_data[2], title => $$cur_row_data[3] }
05a5ca4b 821 )
822 ),
823 } ),
ce556881 824 }
825
aa1d8a87 826 $#{$_[0]} = $result_pos - 1;
ce556881 827 ',
52864fbd 828 'Multiple has_many on multiple branches with underdefined root, HRI-direct torture test',
ce556881 829);
830
fd2d3c95 831
832$infmap = [
833 'single_track.lyrics.track_id', # (0) random optional 1:1:1 chain
834 'year', # (1) non-unique
835 'tracks.cd', # (2) \ together both uniqueness for second multirel
836 'tracks.title', # (3) / and definitive link back to root
837 'single_track.cd.artist.cds.cdid', # (4) to give uniquiness to ...tracks.title below
838 'single_track.cd.artist.cds.year', # (5) non-unique
839 'single_track.cd.artist.artistid', # (6) uniqufies entire parental chain
840 'single_track.cd.artist.cds.genreid', # (7) nullable
841 'single_track.cd.artist.cds.tracks.title', # (8) unique when combined with ...cds.cdid above
842 'single_track.lyrics.lyric_versions.text', # (9) unique combined with the single_track.lyrics 1:1:1
843];
844
845is_deeply (
846 $schema->source('CD')->_resolve_collapse({ as => {map { $infmap->[$_] => $_ } 0 .. $#$infmap} }),
847 {
848 -identifying_columns => [],
849 -identifying_columns_variants => [
850 [ 2 ], [ 6 ],
851 ],
852 single_track => {
853 -identifying_columns => [ 6 ],
854 -is_optional => 1,
855 -is_single => 1,
856 cd => {
857 -identifying_columns => [ 6 ],
858 -is_single => 1,
859 artist => {
860 -identifying_columns => [ 6 ],
861 -is_single => 1,
862 cds => {
863 -identifying_columns => [ 4, 6 ],
864 -is_optional => 1,
865 tracks => {
866 -identifying_columns => [ 4, 6, 8 ],
867 -is_optional => 1,
868 }
869 }
870 }
871 },
872 lyrics => {
873 -identifying_columns => [ 0, 6 ],
874 -is_optional => 1,
875 -is_single => 1,
876 lyric_versions => {
877 -identifying_columns => [ 0, 6, 9 ],
878 -is_optional => 1,
879 },
880 },
881 },
882 tracks => {
883 -identifying_columns => [ 2, 3 ],
884 -is_optional => 1,
885 }
886 },
887 'Correct underdefined root tripple-has-many-torture collapse map constructed'
888);
889
890is_same_src (
891 ($schema->source ('CD')->_mk_row_parser({
892 inflate_map => $infmap,
893 collapse => 1,
894 hri_style => 1,
895 prune_null_branches => 1,
896 }))[0],
897 ' my $rows_pos = 0;
898 my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids);
899
900 while ($cur_row_data = (
901 (
902 $rows_pos >= 0
903 and
904 (
905 $_[0][$rows_pos++]
906 or
907 ( ($rows_pos = -1), undef )
908 )
909 )
910 or
911 ( $_[1] and $_[1]->() )
912 ) ) {
913
914 # do not care about nullability here
915 ( @cur_row_ids{( 0, 2, 3, 4, 6, 8, 9 )} = @{$cur_row_data}[( 0, 2, 3, 4, 6, 8, 9 )] ),
916
917 # cache expensive set of ops in a non-existent rowid slot
918 ( $cur_row_ids{11} = (
919 ( ( defined $cur_row_data->[2] ) && (join "\xFF", q{}, $cur_row_ids{2}, q{} ))
920 or
921 ( ( defined $cur_row_data->[6] ) && (join "\xFF", q{}, $cur_row_ids{6}, q{} ))
922 or
923 "\0$rows_pos\0"
924 )),
925
926 # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2]
927 ( $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{11}} and (unshift @{$_[2]}, $cur_row_data) and last ),
928
929 ( $collapse_idx[0]{$cur_row_ids{11}} //= $_[0][$result_pos++] = { year => $$cur_row_data[1] } ),
930
931 ( (! defined $cur_row_data->[6] ) ? $collapse_idx[0]{$cur_row_ids{11}}{single_track} = undef : do {
932
933 ( $collapse_idx[0]{$cur_row_ids{11}}{single_track} //= ( $collapse_idx[1]{$cur_row_ids{6}} = {} ) ),
934
935 ( $collapse_idx[1]{$cur_row_ids{6}}{cd} //= $collapse_idx[2]{$cur_row_ids{6}} = {} ),
936
937 ( $collapse_idx[2]{$cur_row_ids{6}}{artist} //= ($collapse_idx[3]{$cur_row_ids{6}} = { artistid => $$cur_row_data[6] }) ),
938
939 ( (! defined $cur_row_data->[4] ) ? $collapse_idx[3]{$cur_row_ids{6}}{cds} = [] : do {
940
941 (
942 (! $collapse_idx[4]{$cur_row_ids{4}}{$cur_row_ids{6}} )
943 and
944 push @{$collapse_idx[3]{$cur_row_ids{6}}{cds}}, (
945 $collapse_idx[4]{$cur_row_ids{4}}{$cur_row_ids{6}} = { cdid => $$cur_row_data[4], genreid => $$cur_row_data[7], year => $$cur_row_data[5] }
946 )
947 ),
948
949 ( (! defined $cur_row_data->[8] ) ? $collapse_idx[4]{$cur_row_ids{4}}{$cur_row_ids{6}}{tracks} = [] : do {
950
951 (! $collapse_idx[5]{$cur_row_ids{4}}{$cur_row_ids{6}}{$cur_row_ids{8}} )
952 and
953 push @{$collapse_idx[4]{$cur_row_ids{4}}{$cur_row_ids{6}}{tracks}}, (
954 $collapse_idx[5]{$cur_row_ids{4}}{$cur_row_ids{6}}{$cur_row_ids{8}} = { title => $$cur_row_data[8] }
955 ),
956 } ),
957 } ),
958
959 ( ( ! defined $cur_row_data->[0] ) ? $collapse_idx[1]{ $cur_row_ids{6} }{"lyrics"} = undef : do {
960
961 ( $collapse_idx[1]{ $cur_row_ids{6} }{"lyrics"} //= ( $collapse_idx[6]{ $cur_row_ids{0} }{ $cur_row_ids{6} } = { "track_id" => $cur_row_data->[0] } ) ),
962
963 ( ( ! defined $cur_row_data->[9] ) ? $collapse_idx[6]{ $cur_row_ids{0} }{ $cur_row_ids{6} }{"lyric_versions"} = [] : do {
964 (
965 (! $collapse_idx[7]{ $cur_row_ids{0} }{ $cur_row_ids{6} }{ $cur_row_ids{9} })
966 and
967 push @{$collapse_idx[6]{ $cur_row_ids{0} }{ $cur_row_ids{6} }{"lyric_versions"}}, (
968 $collapse_idx[7]{ $cur_row_ids{0} }{ $cur_row_ids{6} }{ $cur_row_ids{9} } = { "text" => $cur_row_data->[9] }
969 ),
970 ),
971 } ),
972 } ),
973 } ),
974
975 ( (! defined $cur_row_data->[2] ) ? $collapse_idx[0]{$cur_row_ids{11}}{tracks} = [] : do {
976 (
977 (! $collapse_idx[8]{$cur_row_ids{2}}{$cur_row_ids{3}} )
978 and
979 push @{$collapse_idx[0]{$cur_row_ids{11}}{tracks}}, (
980 $collapse_idx[8]{$cur_row_ids{2}}{$cur_row_ids{3}} = { cd => $$cur_row_data[2], title => $$cur_row_data[3] }
981 )
982 ),
983 } ),
984 }
985
986 $#{$_[0]} = $result_pos - 1;
987 ',
988 'Tripple multiple has_many on multiple branches with underdefined root, HRI-direct torture test',
989);
990
c863e102 991is_same_src (
992 ($schema->source ('Owners')->_mk_row_parser({
993 inflate_map => [qw( books.title books.owner )],
994 collapse => 1,
995 prune_null_branches => 1,
996 }))[0],
997 ' my $rows_pos = 0;
998 my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids );
999
1000 while ($cur_row_data = (
164aab8c 1001 (
1002 $rows_pos >= 0
1003 and
1004 (
1005 $_[0][$rows_pos++]
1006 or
1007 ( ($rows_pos = -1), undef )
1008 )
1009 )
c863e102 1010 or
164aab8c 1011 ( $_[1] and $_[1]->() )
c863e102 1012 ) ) {
1013
05a5ca4b 1014 ( @cur_row_ids{0,1} = @{$cur_row_data}[0,1] ),
c863e102 1015
05a5ca4b 1016 ( $cur_row_ids{3} = (
c863e102 1017 ( ( defined $cur_row_data->[1] ) && (join "\xFF", q{}, $cur_row_ids{1}, q{} ))
1018 or
1019 "\0${rows_pos}\0"
05a5ca4b 1020 )),
c863e102 1021
05a5ca4b 1022 ( $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{3}} and (unshift @{$_[2]}, $cur_row_data) and last ),
c863e102 1023
1024 # empty data for the root node
05a5ca4b 1025 ( $collapse_idx[0]{$cur_row_ids{3}} //= $_[0][$result_pos++] = [] ),
c863e102 1026
05a5ca4b 1027 ( ( ! defined $cur_row_data->[0] ) ? $collapse_idx[0]{$cur_row_ids{3}}[1]{"books"} = [] : do {
17f1b61e 1028 ( ! $collapse_idx[1]{$cur_row_ids{0}} )
1029 and
c863e102 1030 push @{$collapse_idx[0]{$cur_row_ids{3}}[1]{books}},
1031 $collapse_idx[1]{$cur_row_ids{0}} = [ { owner => $cur_row_data->[1], title => $cur_row_data->[0] } ]
05a5ca4b 1032 } ),
c863e102 1033 }
1034
1035 $#{$_[0]} = $result_pos - 1; # truncate the passed in array to where we filled it with results
1036 ',
1037 'Non-premultiplied implicit collapse with missing join columns',
1038);
1039
4e9fc3f3 1040done_testing;
1041
1042my $deparser;
cd784aab 1043sub is_same_src { SKIP: {
2fdeef65 1044
3cff955a 1045 skip "Skipping comparison of unicode-poisoned source", 1
2fdeef65 1046 if DBIx::Class::_ENV_::STRESSTEST_UTF8_UPGRADE_GENERATED_COLLAPSER_SOURCE;
1047
4e9fc3f3 1048 $deparser ||= B::Deparse->new;
1049 local $Test::Builder::Level = $Test::Builder::Level + 1;
1050
52864fbd 1051 my ($got, $expect) = @_;
1052
cd784aab 1053 skip "Not testing equality of source containing defined-or operator on this perl $]", 1
750a4ad2 1054 if ( "$]" < 5.010 and $expect =~ m!\Q//=! );
cd784aab 1055
01b25f12 1056 $expect =~ s/__NBC__/perlstring($DBIx::Class::ResultSource::RowParser::Util::null_branch_class)/ge;
52864fbd 1057
9f7d5590 1058 $expect = " { use strict; use warnings FATAL => 'uninitialized';\n$expect\n }";
bdbd2ae8 1059
52864fbd 1060 my @normalized = map {
4e9fc3f3 1061 my $cref = eval "sub { $_ }" or do {
1062 fail "Coderef does not compile!\n\n$@\n\n$_";
1063 return undef;
1064 };
1065 $deparser->coderef2text($cref);
52864fbd 1066 } ($got, $expect);
1067
1068 &is (@normalized, $_[2]||() ) or do {
1069 eval { require Test::Differences }
1070 ? &Test::Differences::eq_or_diff( @normalized, $_[2]||() )
e81b50f4 1071 : note ("Original sources:\n\n$got\n\n$expect\n")
1072 ;
1073 exit 1;
52864fbd 1074 };
cd784aab 1075} }