@@ -258,7 +258,7 @@ TStatus AnnotateStage(const TExprNode::TPtr& stage, TExprContext& ctx) {
258
258
}
259
259
260
260
THashMap<TStringBuf, THashMap<TStringBuf, const TTypeAnnotationNode*>>
261
- ParseJoinInputType (const TStructExprType& rowType, TStringBuf tableLabel , TExprContext& ctx, bool optional) {
261
+ ParseJoinInputType (const TStructExprType& rowType, const THashSet< TStringBuf>& tableLabels , TExprContext& ctx, bool optional) {
262
262
THashMap<TStringBuf, THashMap<TStringBuf, const TTypeAnnotationNode*>> result;
263
263
for (auto member : rowType.GetItems ()) {
264
264
TStringBuf label, column;
@@ -268,7 +268,7 @@ ParseJoinInputType(const TStructExprType& rowType, TStringBuf tableLabel, TExprC
268
268
column = member->GetName ();
269
269
}
270
270
const bool isSystemKeyColumn = column.starts_with (" _yql_dq_key_" );
271
- if (label.empty () && tableLabel. empty () && !isSystemKeyColumn) {
271
+ if (label.empty () && (tableLabels. size () == 1 && tableLabels. begin ()-> empty () ) && !isSystemKeyColumn) {
272
272
ctx.AddError (TIssue (TStringBuilder () << " Invalid join input type " << FormatType (&rowType)));
273
273
result.clear ();
274
274
return result;
@@ -277,23 +277,30 @@ ParseJoinInputType(const TStructExprType& rowType, TStringBuf tableLabel, TExprC
277
277
if (optional && !memberType->IsOptionalOrNull ()) {
278
278
memberType = ctx.MakeType <TOptionalExprType>(memberType);
279
279
}
280
- if (!tableLabel. empty () && label. empty () ) {
281
- result[tableLabel][member-> GetName ()] = memberType ;
282
- } else {
280
+ if (tableLabels. size () > 1 ) {
281
+ YQL_ENSURE (label) ;
282
+ YQL_ENSURE (column);
283
283
result[label][column] = memberType;
284
+ } else {
285
+ YQL_ENSURE (tableLabels.size () == 1 );
286
+ if (!(tableLabels.begin ())->empty ()) {
287
+ result[*(tableLabels.begin ())][member->GetName ()] = memberType;
288
+ } else {
289
+ result[label][column] = memberType;
290
+ }
284
291
}
285
292
}
286
293
return result;
287
294
}
288
295
289
296
template <bool IsMapJoin>
290
297
const TStructExprType* GetDqJoinResultType (TPositionHandle pos, const TStructExprType& leftRowType,
291
- const TStringBuf& leftLabel , const TStructExprType& rightRowType, const TStringBuf& rightLabel ,
298
+ const THashSet< TStringBuf>& leftLabels , const TStructExprType& rightRowType, const THashSet< TStringBuf>& rightLabels ,
292
299
const TStringBuf& joinType, const TDqJoinKeyTupleList& joinKeys, TExprContext& ctx)
293
300
{
294
301
// check left
295
302
bool isLeftOptional = IsLeftJoinSideOptional (joinType);
296
- auto leftType = ParseJoinInputType (leftRowType, leftLabel , ctx, isLeftOptional);
303
+ auto leftType = ParseJoinInputType (leftRowType, leftLabels , ctx, isLeftOptional);
297
304
if (leftType.empty () && joinType != " Cross" ) {
298
305
TStringStream str; str << " Cannot parse left join input type: " ;
299
306
leftRowType.Out (str);
@@ -303,7 +310,7 @@ const TStructExprType* GetDqJoinResultType(TPositionHandle pos, const TStructExp
303
310
304
311
// check right
305
312
bool isRightOptional = IsRightJoinSideOptional (joinType);
306
- auto rightType = ParseJoinInputType (rightRowType, rightLabel , ctx, isRightOptional);
313
+ auto rightType = ParseJoinInputType (rightRowType, rightLabels , ctx, isRightOptional);
307
314
if (rightType.empty () && joinType != " Cross" ) {
308
315
TStringStream str; str << " Cannot parse right join input type: " ;
309
316
rightRowType.Out (str);
@@ -331,11 +338,11 @@ const TStructExprType* GetDqJoinResultType(TPositionHandle pos, const TStructExp
331
338
auto rightKeyLabel = key.RightLabel ().Value ();
332
339
auto rightKeyColumn = key.RightColumn ().Value ();
333
340
334
- if (leftLabel && leftLabel != leftKeyLabel) {
341
+ if (leftLabels. size () && !leftLabels. contains ( leftKeyLabel) ) {
335
342
ctx.AddError (TIssue (ctx.GetPosition (pos), " different labels for left table" ));
336
343
return nullptr ;
337
344
}
338
- if (rightLabel && rightLabel != rightKeyLabel) {
345
+ if (rightLabels. size () && !rightLabels. contains ( rightKeyLabel) ) {
339
346
ctx.AddError (TIssue (ctx.GetPosition (pos), " different labels for right table" ));
340
347
return nullptr ;
341
348
}
@@ -402,14 +409,26 @@ const TStructExprType* GetDqJoinResultType(const TExprNode::TPtr& input, bool st
402
409
}
403
410
404
411
if (!input->Child (TDqJoin::idx_LeftLabel)->IsCallable (" Void" )) {
405
- if (!EnsureAtom (*input->Child (TDqJoin::idx_LeftLabel), ctx)) {
406
- return nullptr ;
412
+ if ((input->Child (TDqJoin::idx_LeftLabel)->IsAtom ())) {
413
+ if (!EnsureAtom (*input->Child (TDqJoin::idx_LeftLabel), ctx)) {
414
+ return nullptr ;
415
+ }
416
+ } else {
417
+ if (!EnsureTupleOfAtoms (*input->Child (TDqJoin::idx_LeftLabel), ctx)) {
418
+ return nullptr ;
419
+ }
407
420
}
408
421
}
409
422
410
423
if (!input->Child (TDqJoin::idx_RightLabel)->IsCallable (" Void" )) {
411
- if (!EnsureAtom (*input->Child (TDqJoin::idx_RightLabel), ctx)) {
412
- return nullptr ;
424
+ if ((input->Child (TDqJoin::idx_RightLabel)->IsAtom ())) {
425
+ if (!EnsureAtom (*input->Child (TDqJoin::idx_RightLabel), ctx)) {
426
+ return nullptr ;
427
+ }
428
+ } else {
429
+ if (!EnsureTupleOfAtoms (*input->Child (TDqJoin::idx_RightLabel), ctx)) {
430
+ return nullptr ;
431
+ }
413
432
}
414
433
}
415
434
@@ -459,18 +478,32 @@ const TStructExprType* GetDqJoinResultType(const TExprNode::TPtr& input, bool st
459
478
return nullptr ;
460
479
}
461
480
auto leftStructType = leftInputItemType.Cast <TStructExprType>();
462
- auto leftTableLabel = join.LeftLabel ().Maybe <TCoAtom>()
463
- ? join.LeftLabel ().Cast <TCoAtom>().Value ()
464
- : TStringBuf (" " );
481
+ THashSet<TStringBuf> leftTableLabels;
482
+ if (join.LeftLabel ().Maybe <TCoAtom>()) {
483
+ leftTableLabels.emplace (join.LeftLabel ().Cast <TCoAtom>().Value ());
484
+ } else if (join.LeftLabel ().Maybe <TCoAtomList>()) {
485
+ for (auto label : join.LeftLabel ().Cast <TCoAtomList>()) {
486
+ leftTableLabels.emplace (label.Value ());
487
+ }
488
+ } else {
489
+ leftTableLabels.emplace (" " );
490
+ }
465
491
466
492
const auto & rightInputItemType = GetSeqItemType (*rightInputType);
467
493
if (!EnsureStructType (join.Pos (), rightInputItemType, ctx)) {
468
494
return nullptr ;
469
495
}
470
496
auto rightStructType = rightInputItemType.Cast <TStructExprType>();
471
- auto rightTableLabel = join.RightLabel ().Maybe <TCoAtom>()
472
- ? join.RightLabel ().Cast <TCoAtom>().Value ()
473
- : TStringBuf (" " );
497
+ THashSet<TStringBuf> rightTableLabels;
498
+ if (join.RightLabel ().Maybe <TCoAtom>()) {
499
+ rightTableLabels.emplace (join.RightLabel ().Cast <TCoAtom>().Value ());
500
+ } else if (join.RightLabel ().Maybe <TCoAtomList>()) {
501
+ for (auto label : join.RightLabel ().Cast <TCoAtomList>()) {
502
+ rightTableLabels.emplace (label.Value ());
503
+ }
504
+ } else {
505
+ rightTableLabels.emplace (" " );
506
+ }
474
507
475
508
if (input->ChildrenSize () > TDqJoin::idx_JoinAlgoOptions) {
476
509
const auto & joinAlgo = *input->Child (TDqJoin::idx_JoinAlgo);
@@ -511,9 +544,9 @@ const TStructExprType* GetDqJoinResultType(const TExprNode::TPtr& input, bool st
511
544
}
512
545
}
513
546
514
- return GetDqJoinResultType<IsMapJoin>(join.Pos (), *leftStructType, leftTableLabel , *rightStructType,
515
- rightTableLabel , join.JoinType (), join.JoinKeys (), ctx);
516
- }
547
+ return GetDqJoinResultType<IsMapJoin>(join.Pos (), *leftStructType, leftTableLabels , *rightStructType,
548
+ rightTableLabels , join.JoinType (), join.JoinKeys (), ctx);
549
+ }
517
550
518
551
} // unnamed
519
552
@@ -689,12 +722,31 @@ TStatus AnnotateDqCnStreamLookup(const TExprNode::TPtr& input, TExprContext& ctx
689
722
if (!EnsureStructType (input->Pos (), rightRowType, ctx)) {
690
723
return TStatus::Error;
691
724
}
725
+
726
+ THashSet<TStringBuf> leftLabels;
727
+ if (cnStreamLookup.LeftLabel ().Maybe <TCoAtom>()) {
728
+ leftLabels.emplace (cnStreamLookup.LeftLabel ().Cast <TCoAtom>().Value ());
729
+ } else {
730
+ for (auto label : cnStreamLookup.LeftLabel ().Cast <TCoAtomList>()) {
731
+ leftLabels.emplace (label.Value ());
732
+ }
733
+ }
734
+
735
+ THashSet<TStringBuf> rightLabels;
736
+ if (cnStreamLookup.RightLabel ().Maybe <TCoAtom>()) {
737
+ rightLabels.emplace (cnStreamLookup.RightLabel ().Cast <TCoAtom>().Value ());
738
+ } else {
739
+ for (auto label : cnStreamLookup.RightLabel ().Cast <TCoAtomList>()) {
740
+ rightLabels.emplace (label.Value ());
741
+ }
742
+ }
743
+
692
744
const auto outputRowType = GetDqJoinResultType<true >(
693
745
input->Pos (),
694
746
*leftRowType.Cast <TStructExprType>(),
695
- cnStreamLookup. LeftLabel (). Cast <TCoAtom>(). StringValue () ,
747
+ leftLabels ,
696
748
*rightRowType.Cast <TStructExprType>(),
697
- cnStreamLookup. RightLabel (). StringValue () ,
749
+ rightLabels ,
698
750
cnStreamLookup.JoinType ().StringValue (),
699
751
cnStreamLookup.JoinKeys (),
700
752
ctx
0 commit comments