@@ -298,7 +298,8 @@ class TLineageScanner {
298
298
}
299
299
300
300
TMaybe<TFieldsLineage> ScanExprLineage (const TExprNode& node, const TExprNode* arg, const TLineage* src,
301
- TNodeMap<TMaybe<TFieldsLineage>>& visited) {
301
+ TNodeMap<TMaybe<TFieldsLineage>>& visited,
302
+ const THashMap<const TExprNode*, TString>& flattenColumns) {
302
303
if (&node == arg) {
303
304
return Nothing ();
304
305
}
@@ -308,6 +309,10 @@ class TLineageScanner {
308
309
return it->second ;
309
310
}
310
311
312
+ if (auto itFlatten = flattenColumns.find (&node); itFlatten != flattenColumns.end ()) {
313
+ return it->second = *(*src->Fields ).FindPtr (itFlatten->second );
314
+ }
315
+
311
316
if (node.IsCallable (" Member" )) {
312
317
if (&node.Head () == arg && src) {
313
318
return it->second = *(*src->Fields ).FindPtr (node.Tail ().Content ());
@@ -325,7 +330,7 @@ class TLineageScanner {
325
330
}
326
331
}
327
332
328
- auto inner = ScanExprLineage (node.Head (), arg, src, visited);
333
+ auto inner = ScanExprLineage (node.Head (), arg, src, visited, {} );
329
334
if (!inner) {
330
335
return Nothing ();
331
336
}
@@ -365,7 +370,7 @@ class TLineageScanner {
365
370
continue ;
366
371
}
367
372
368
- auto inner = ScanExprLineage (*child, arg, src, visited);
373
+ auto inner = ScanExprLineage (*child, arg, src, visited, {} );
369
374
if (!inner) {
370
375
return Nothing ();
371
376
}
@@ -392,10 +397,11 @@ class TLineageScanner {
392
397
}
393
398
394
399
void MergeLineageFromUsedFields (const TExprNode& expr, const TExprNode& arg, const TLineage& src,
395
- TFieldLineageSet& dst, const TString& newTransforms = " " ) {
400
+ TFieldLineageSet& dst, const THashMap<const TExprNode*, TString>& flattenColumns,
401
+ const TString& newTransforms = " " ) {
396
402
397
403
TNodeMap<TMaybe<TFieldsLineage>> visited;
398
- auto res = ScanExprLineage (expr, &arg, &src, visited);
404
+ auto res = ScanExprLineage (expr, &arg, &src, visited, flattenColumns );
399
405
if (!res) {
400
406
for (const auto & f : *src.Fields ) {
401
407
for (const auto & i: f.second .Items ) {
@@ -410,7 +416,8 @@ class TLineageScanner {
410
416
}
411
417
412
418
void MergeLineageFromUsedFields (const TExprNode& expr, const TExprNode& arg, const TLineage& src,
413
- TFieldsLineage& dst, bool produceStruct, const TString& newTransforms = " " ) {
419
+ TFieldsLineage& dst, bool produceStruct, const THashMap<const TExprNode*, TString>& flattenColumns,
420
+ const TString& newTransforms = " " ) {
414
421
if (produceStruct) {
415
422
auto root = &expr;
416
423
while (root->IsCallable (" Just" )) {
@@ -427,7 +434,7 @@ class TLineageScanner {
427
434
for (const auto & x : root->Children ()) {
428
435
auto fieldName = x->Head ().Content ();
429
436
auto & s = (*dst.StructItems )[fieldName];
430
- MergeLineageFromUsedFields (x->Tail (), arg, src, s, newTransforms);
437
+ MergeLineageFromUsedFields (x->Tail (), arg, src, s, flattenColumns, newTransforms);
431
438
}
432
439
} else if (root->IsCallable (" Member" ) && &root->Head () == &arg) {
433
440
auto fieldName = root->Tail ().Content ();
@@ -436,11 +443,11 @@ class TLineageScanner {
436
443
}
437
444
}
438
445
439
- MergeLineageFromUsedFields (expr, arg, src, dst.Items , newTransforms);
446
+ MergeLineageFromUsedFields (expr, arg, src, dst.Items , flattenColumns, newTransforms);
440
447
}
441
448
442
449
void FillStructLineage (TLineage& lineage, const TExprNode* value, const TExprNode& arg, const TLineage& innerLineage,
443
- const TTypeAnnotationNode* extType) {
450
+ const TTypeAnnotationNode* extType, const THashMap< const TExprNode*, TString>& flattenColumns ) {
444
451
TMaybe<TString> oneField;
445
452
if (value && value->IsCallable (" Member" ) && &value->Head () == &arg) {
446
453
TString field (value->Tail ().Content ());
@@ -462,8 +469,8 @@ class TLineageScanner {
462
469
TLineage left, right;
463
470
left.Fields .ConstructInPlace ();
464
471
right.Fields .ConstructInPlace ();
465
- FillStructLineage (left, value->Child (1 ), arg, innerLineage, extType);
466
- FillStructLineage (right, value->Child (2 ), arg, innerLineage, extType);
472
+ FillStructLineage (left, value->Child (1 ), arg, innerLineage, extType, {} );
473
+ FillStructLineage (right, value->Child (2 ), arg, innerLineage, extType, {} );
467
474
for (const auto & f : *left.Fields ) {
468
475
auto & res = (*lineage.Fields )[f.first ];
469
476
res.Items .insert (f.second .Items .begin (), f.second .Items .end ());
@@ -483,7 +490,7 @@ class TLineageScanner {
483
490
auto & res = (*lineage.Fields )[field];
484
491
const auto & expr = child->Tail ();
485
492
TString newTransforms;
486
- auto root = &expr;
493
+ const TExprNode* root = &expr;
487
494
while (root->IsCallable (" Just" )) {
488
495
root = &root->Head ();
489
496
}
@@ -492,7 +499,7 @@ class TLineageScanner {
492
499
newTransforms = " Copy" ;
493
500
}
494
501
495
- MergeLineageFromUsedFields (expr, arg, innerLineage, res, true , newTransforms);
502
+ MergeLineageFromUsedFields (expr, arg, innerLineage, res, true , flattenColumns, newTransforms);
496
503
}
497
504
498
505
return ;
@@ -526,13 +533,30 @@ class TLineageScanner {
526
533
const auto & lambda = node.Tail ();
527
534
const auto & arg = lambda.Head ().Head ();
528
535
const auto & body = lambda.Tail ();
529
- const TExprNode* value;
536
+ THashMap<const TExprNode*, TString> flattenColumns;
537
+ const TExprNode* value = &body.Tail ();
530
538
if (body.IsCallable ({" OptionalIf" , " FlatListIf" })) {
531
539
value = &body.Tail ();
532
540
} else if (body.IsCallable (" Just" )) {
533
541
value = &body.Head ();
534
542
} else if (body.IsCallable ({" FlatMap" , " OrderedFlatMap" })) {
535
- value = &body.Head ();
543
+ if (lambda.GetTypeAnn ()->GetKind () == ETypeAnnotationKind::List) {
544
+ value = &body;
545
+ while (value->IsCallable ({" FlatMap" , " OrderedFlatMap" })) {
546
+ if (value->Head ().IsCallable (" Member" ) && &value->Head ().Head () == &arg) {
547
+ TString field (value->Head ().Tail ().Content ());
548
+ flattenColumns.emplace (value->Tail ().Head ().HeadPtr ().Get (), field);
549
+ }
550
+ value = &value->Tail ().Tail ();
551
+ }
552
+ if (value->IsCallable (" Just" )) {
553
+ value = &value->Head ();
554
+ } else if (value->IsCallable ({" OptionalIf" , " FlatListIf" })) {
555
+ value = &value->Tail ();
556
+ }
557
+ } else {
558
+ value = &body.Head ();
559
+ }
536
560
} else {
537
561
Warning (body);
538
562
return ;
@@ -544,7 +568,7 @@ class TLineageScanner {
544
568
}
545
569
546
570
lineage.Fields .ConstructInPlace ();
547
- FillStructLineage (lineage, value, arg, innerLineage, GetSeqItemType (body.GetTypeAnn ()));
571
+ FillStructLineage (lineage, value, arg, innerLineage, GetSeqItemType (body.GetTypeAnn ()), flattenColumns );
548
572
}
549
573
550
574
void HandleAggregate (TLineage& lineage, const TExprNode& node) {
@@ -578,12 +602,12 @@ class TLineageScanner {
578
602
// merge all used fields from init/update handlers
579
603
auto initHandler = payload->Child (1 )->Child (1 );
580
604
auto updateHandler = payload->Child (1 )->Child (2 );
581
- MergeLineageFromUsedFields (initHandler->Tail (), initHandler->Head ().Head (), innerLineage, source, false );
582
- MergeLineageFromUsedFields (updateHandler->Tail (), updateHandler->Head ().Head (), innerLineage, source, false );
605
+ MergeLineageFromUsedFields (initHandler->Tail (), initHandler->Head ().Head (), innerLineage, source, false , {} );
606
+ MergeLineageFromUsedFields (updateHandler->Tail (), updateHandler->Head ().Head (), innerLineage, source, false , {} );
583
607
} else if (payload->Child (1 )->IsCallable (" AggApply" )) {
584
608
auto extractHandler = payload->Child (1 )->Child (2 );
585
609
bool produceStruct = payload->Child (1 )->Head ().Content () == " some" ;
586
- MergeLineageFromUsedFields (extractHandler->Tail (), extractHandler->Head ().Head (), innerLineage, source, produceStruct);
610
+ MergeLineageFromUsedFields (extractHandler->Tail (), extractHandler->Head ().Head (), innerLineage, source, produceStruct, {} );
587
611
} else {
588
612
Warning (*payload->Child (1 ));
589
613
lineage.Fields .Clear ();
@@ -612,7 +636,7 @@ class TLineageScanner {
612
636
}
613
637
614
638
lineage.Fields .ConstructInPlace ();
615
- FillStructLineage (lineage, nullptr , arg, innerLineage, GetSeqItemType (body.GetTypeAnn ()));
639
+ FillStructLineage (lineage, nullptr , arg, innerLineage, GetSeqItemType (body.GetTypeAnn ()), {} );
616
640
}
617
641
618
642
void HandlePartitionByKeys (TLineage& lineage, const TExprNode& node) {
@@ -630,7 +654,7 @@ class TLineageScanner {
630
654
}
631
655
632
656
lineage.Fields .ConstructInPlace ();
633
- FillStructLineage (lineage, nullptr , arg, innerLineage, GetSeqItemType (body.GetTypeAnn ()));
657
+ FillStructLineage (lineage, nullptr , arg, innerLineage, GetSeqItemType (body.GetTypeAnn ()), {} );
634
658
}
635
659
636
660
void HandleExtend (TLineage& lineage, const TExprNode& node) {
@@ -709,8 +733,8 @@ class TLineageScanner {
709
733
auto & res = (*lineage.Fields )[sessionColumn->Content ()];
710
734
const auto & initHandler = node.Child (4 )->Child (2 );
711
735
const auto & updateHandler = node.Child (4 )->Child (2 );
712
- MergeLineageFromUsedFields (initHandler->Tail (), initHandler->Head ().Head (), innerLineage, res, false );
713
- MergeLineageFromUsedFields (updateHandler->Tail (), updateHandler->Head ().Head (), innerLineage, res, false );
736
+ MergeLineageFromUsedFields (initHandler->Tail (), initHandler->Head ().Head (), innerLineage, res, false , {} );
737
+ MergeLineageFromUsedFields (updateHandler->Tail (), updateHandler->Head ().Head (), innerLineage, res, false , {} );
714
738
}
715
739
}
716
740
@@ -730,12 +754,12 @@ class TLineageScanner {
730
754
} else if (list->Tail ().IsCallable ({" Lag" ," Lead" ," Rank" ," DenseRank" ," PercentRank" })) {
731
755
const auto & lambda = list->Tail ().Child (1 );
732
756
bool produceStruct = list->Tail ().IsCallable ({" Lag" ," Lead" });
733
- MergeLineageFromUsedFields (lambda->Tail (), lambda->Head ().Head (), innerLineage, res, produceStruct);
757
+ MergeLineageFromUsedFields (lambda->Tail (), lambda->Head ().Head (), innerLineage, res, produceStruct, {} );
734
758
} else if (list->Tail ().IsCallable (" WindowTraits" )) {
735
759
const auto & initHandler = list->Tail ().Child (1 );
736
760
const auto & updateHandler = list->Tail ().Child (2 );
737
- MergeLineageFromUsedFields (initHandler->Tail (), initHandler->Head ().Head (), innerLineage, res, false );
738
- MergeLineageFromUsedFields (updateHandler->Tail (), updateHandler->Head ().Head (), innerLineage, res, false );
761
+ MergeLineageFromUsedFields (initHandler->Tail (), initHandler->Head ().Head (), innerLineage, res, false , {} );
762
+ MergeLineageFromUsedFields (updateHandler->Tail (), updateHandler->Head ().Head (), innerLineage, res, false , {} );
739
763
} else {
740
764
lineage.Fields .Clear ();
741
765
return ;
@@ -850,15 +874,15 @@ class TLineageScanner {
850
874
if (child->IsCallable (" AsStruct" )) {
851
875
for (const auto & f : child->Children ()) {
852
876
TNodeMap<TMaybe<TFieldsLineage>> visited;
853
- auto res = ScanExprLineage (f->Tail (), nullptr , nullptr , visited);
877
+ auto res = ScanExprLineage (f->Tail (), nullptr , nullptr , visited, {} );
854
878
if (res) {
855
879
auto name = f->Head ().Content ();
856
880
(*lineage.Fields )[name].MergeFrom (*res);
857
881
}
858
882
}
859
883
} else {
860
884
TNodeMap<TMaybe<TFieldsLineage>> visited;
861
- auto res = ScanExprLineage (*child, nullptr , nullptr , visited);
885
+ auto res = ScanExprLineage (*child, nullptr , nullptr , visited, {} );
862
886
if (res) {
863
887
for (const auto & i : structType->GetItems ()) {
864
888
if (i->GetName ().StartsWith (" _yql_sys_" )) {
0 commit comments