@@ -461,6 +461,9 @@ var (
461
461
cannotDistributeVectorSearchErr = newQueryNotSupportedError (
462
462
"vector search operation cannot be distributed" ,
463
463
)
464
+ cannotDistributeSystemColumnsAndBufferedWrites = newQueryNotSupportedError (
465
+ "system column (that requires MVCC decoding) is requested when writes have been buffered" ,
466
+ )
464
467
)
465
468
466
469
// mustWrapNode returns true if a node has no DistSQL-processor equivalent.
@@ -546,6 +549,7 @@ func checkSupportForPlanNode(
546
549
node planNode ,
547
550
distSQLVisitor * distSQLExprCheckVisitor ,
548
551
sd * sessiondata.SessionData ,
552
+ txnHasBufferedWrites bool ,
549
553
) (retRec distRecommendation , retErr error ) {
550
554
if buildutil .CrdbTestBuild {
551
555
defer func () {
@@ -563,19 +567,19 @@ func checkSupportForPlanNode(
563
567
return shouldDistribute , nil
564
568
565
569
case * distinctNode :
566
- return checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd )
570
+ return checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd , txnHasBufferedWrites )
567
571
568
572
case * exportNode :
569
- return checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd )
573
+ return checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd , txnHasBufferedWrites )
570
574
571
575
case * filterNode :
572
576
if err := checkExprForDistSQL (n .filter , distSQLVisitor ); err != nil {
573
577
return cannotDistribute , err
574
578
}
575
- return checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd )
579
+ return checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd , txnHasBufferedWrites )
576
580
577
581
case * groupNode :
578
- rec , err := checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd )
582
+ rec , err := checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd , txnHasBufferedWrites )
579
583
if err != nil {
580
584
return cannotDistribute , err
581
585
}
@@ -604,10 +608,14 @@ func checkSupportForPlanNode(
604
608
// TODO(nvanbenschoten): lift this restriction.
605
609
return cannotDistribute , cannotDistributeRowLevelLockingErr
606
610
}
607
- return checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd )
611
+ if txnHasBufferedWrites && n .fetch .requiresMVCCDecoding () {
612
+ // TODO(#144166): relax this.
613
+ return cannotDistribute , cannotDistributeSystemColumnsAndBufferedWrites
614
+ }
615
+ return checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd , txnHasBufferedWrites )
608
616
609
617
case * invertedFilterNode :
610
- return checkSupportForInvertedFilterNode (ctx , n , distSQLVisitor , sd )
618
+ return checkSupportForInvertedFilterNode (ctx , n , distSQLVisitor , sd , txnHasBufferedWrites )
611
619
612
620
case * invertedJoinNode :
613
621
if n .fetch .lockingStrength != descpb .ScanLockingStrength_FOR_NONE {
@@ -617,10 +625,14 @@ func checkSupportForPlanNode(
617
625
// TODO(nvanbenschoten): lift this restriction.
618
626
return cannotDistribute , cannotDistributeRowLevelLockingErr
619
627
}
628
+ if txnHasBufferedWrites && n .fetch .requiresMVCCDecoding () {
629
+ // TODO(#144166): relax this.
630
+ return cannotDistribute , cannotDistributeSystemColumnsAndBufferedWrites
631
+ }
620
632
if err := checkExprForDistSQL (n .onExpr , distSQLVisitor ); err != nil {
621
633
return cannotDistribute , err
622
634
}
623
- rec , err := checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd )
635
+ rec , err := checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd , txnHasBufferedWrites )
624
636
if err != nil {
625
637
return cannotDistribute , err
626
638
}
@@ -633,11 +645,11 @@ func checkSupportForPlanNode(
633
645
if err := checkExprForDistSQL (n .pred .onCond , distSQLVisitor ); err != nil {
634
646
return cannotDistribute , err
635
647
}
636
- recLeft , err := checkSupportForPlanNode (ctx , n .left , distSQLVisitor , sd )
648
+ recLeft , err := checkSupportForPlanNode (ctx , n .left , distSQLVisitor , sd , txnHasBufferedWrites )
637
649
if err != nil {
638
650
return cannotDistribute , err
639
651
}
640
- recRight , err := checkSupportForPlanNode (ctx , n .right , distSQLVisitor , sd )
652
+ recRight , err := checkSupportForPlanNode (ctx , n .right , distSQLVisitor , sd , txnHasBufferedWrites )
641
653
if err != nil {
642
654
return cannotDistribute , err
643
655
}
@@ -658,7 +670,7 @@ func checkSupportForPlanNode(
658
670
// Note that we don't need to check whether we support distribution of
659
671
// n.countExpr or n.offsetExpr because those expressions are evaluated
660
672
// locally, during the physical planning.
661
- return checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd )
673
+ return checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd , txnHasBufferedWrites )
662
674
663
675
case * lookupJoinNode :
664
676
if n .remoteLookupExpr != nil || n .remoteOnlyLookups {
@@ -672,7 +684,10 @@ func checkSupportForPlanNode(
672
684
// TODO(nvanbenschoten): lift this restriction.
673
685
return cannotDistribute , cannotDistributeRowLevelLockingErr
674
686
}
675
-
687
+ if txnHasBufferedWrites && n .fetch .requiresMVCCDecoding () {
688
+ // TODO(#144166): relax this.
689
+ return cannotDistribute , cannotDistributeSystemColumnsAndBufferedWrites
690
+ }
676
691
if err := checkExprForDistSQL (n .lookupExpr , distSQLVisitor ); err != nil {
677
692
return cannotDistribute , err
678
693
}
@@ -682,7 +697,7 @@ func checkSupportForPlanNode(
682
697
if err := checkExprForDistSQL (n .onCond , distSQLVisitor ); err != nil {
683
698
return cannotDistribute , err
684
699
}
685
- rec , err := checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd )
700
+ rec , err := checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd , txnHasBufferedWrites )
686
701
if err != nil {
687
702
return cannotDistribute , err
688
703
}
@@ -699,15 +714,15 @@ func checkSupportForPlanNode(
699
714
return cannotDistribute , err
700
715
}
701
716
}
702
- return checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd )
717
+ return checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd , txnHasBufferedWrites )
703
718
704
719
case * renderNode :
705
720
for _ , e := range n .render {
706
721
if err := checkExprForDistSQL (e , distSQLVisitor ); err != nil {
707
722
return cannotDistribute , err
708
723
}
709
724
}
710
- return checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd )
725
+ return checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd , txnHasBufferedWrites )
711
726
712
727
case * scanNode :
713
728
if n .lockingStrength != descpb .ScanLockingStrength_FOR_NONE {
@@ -721,6 +736,10 @@ func checkSupportForPlanNode(
721
736
// This is a locality optimized scan.
722
737
return cannotDistribute , localityOptimizedOpNotDistributableErr
723
738
}
739
+ if txnHasBufferedWrites && n .fetchPlanningInfo .requiresMVCCDecoding () {
740
+ // TODO(#144166): relax this.
741
+ return cannotDistribute , cannotDistributeSystemColumnsAndBufferedWrites
742
+ }
724
743
scanRec := canDistribute
725
744
if n .estimatedRowCount != 0 {
726
745
var suffix string
@@ -748,7 +767,7 @@ func checkSupportForPlanNode(
748
767
return scanRec , nil
749
768
750
769
case * sortNode :
751
- rec , err := checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd )
770
+ rec , err := checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd , txnHasBufferedWrites )
752
771
if err != nil {
753
772
return cannotDistribute , err
754
773
}
@@ -765,7 +784,7 @@ func checkSupportForPlanNode(
765
784
return rec .compose (sortRec ), nil
766
785
767
786
case * topKNode :
768
- rec , err := checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd )
787
+ rec , err := checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd , txnHasBufferedWrites )
769
788
if err != nil {
770
789
return cannotDistribute , err
771
790
}
@@ -785,11 +804,11 @@ func checkSupportForPlanNode(
785
804
return canDistribute , nil
786
805
787
806
case * unionNode :
788
- recLeft , err := checkSupportForPlanNode (ctx , n .left , distSQLVisitor , sd )
807
+ recLeft , err := checkSupportForPlanNode (ctx , n .left , distSQLVisitor , sd , txnHasBufferedWrites )
789
808
if err != nil {
790
809
return cannotDistribute , err
791
810
}
792
- recRight , err := checkSupportForPlanNode (ctx , n .right , distSQLVisitor , sd )
811
+ recRight , err := checkSupportForPlanNode (ctx , n .right , distSQLVisitor , sd , txnHasBufferedWrites )
793
812
if err != nil {
794
813
return cannotDistribute , err
795
814
}
@@ -819,7 +838,7 @@ func checkSupportForPlanNode(
819
838
return cannotDistribute , cannotDistributeVectorSearchErr
820
839
821
840
case * windowNode :
822
- rec , err := checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd )
841
+ rec , err := checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd , txnHasBufferedWrites )
823
842
if err != nil {
824
843
return cannotDistribute , err
825
844
}
@@ -845,6 +864,10 @@ func checkSupportForPlanNode(
845
864
// TODO(nvanbenschoten): lift this restriction.
846
865
return cannotDistribute , cannotDistributeRowLevelLockingErr
847
866
}
867
+ if txnHasBufferedWrites && side .fetch .requiresMVCCDecoding () {
868
+ // TODO(#144166): relax this.
869
+ return cannotDistribute , cannotDistributeSystemColumnsAndBufferedWrites
870
+ }
848
871
}
849
872
if err := checkExprForDistSQL (n .onCond , distSQLVisitor ); err != nil {
850
873
return cannotDistribute , err
@@ -864,8 +887,9 @@ func checkSupportForInvertedFilterNode(
864
887
n * invertedFilterNode ,
865
888
distSQLVisitor * distSQLExprCheckVisitor ,
866
889
sd * sessiondata.SessionData ,
890
+ txnHasBufferedWrites bool ,
867
891
) (distRecommendation , error ) {
868
- rec , err := checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd )
892
+ rec , err := checkSupportForPlanNode (ctx , n .input , distSQLVisitor , sd , txnHasBufferedWrites )
869
893
if err != nil {
870
894
return cannotDistribute , err
871
895
}
@@ -5399,7 +5423,16 @@ func checkScanParallelizationIfLocal(
5399
5423
if len (n .reqOrdering ) == 0 && n .parallelize {
5400
5424
hasScanNodeToParallelize = true
5401
5425
}
5402
- case * distinctNode , * explainVecNode , * indexJoinNode , * limitNode ,
5426
+ if n .fetchPlanningInfo .requiresMVCCDecoding () {
5427
+ prohibitParallelization = true
5428
+ return
5429
+ }
5430
+ case * indexJoinNode :
5431
+ if n .fetch .requiresMVCCDecoding () {
5432
+ prohibitParallelization = true
5433
+ return
5434
+ }
5435
+ case * distinctNode , * explainVecNode , * limitNode ,
5403
5436
* ordinalityNode , * sortNode , * unionNode , * valuesNode :
5404
5437
default :
5405
5438
prohibitParallelization = true
0 commit comments