@@ -5289,7 +5289,7 @@ func logAndSanitizeExportDestination(ctx context.Context, dest string) error {
5289
5289
// processors eagerly move into the draining state which will cancel the context
5290
5290
// of parallel TableReaders which might "poison" the transaction.
5291
5291
func checkScanParallelizationIfLocal (
5292
- ctx context.Context , plan * planComponents , c * localScanParallelizationChecker ,
5292
+ ctx context.Context , plan * planComponents ,
5293
5293
) (prohibitParallelization , hasScanNodeToParallelize bool ) {
5294
5294
if plan .main .planNode == nil || len (plan .cascades ) != 0 ||
5295
5295
len (plan .checkPlans ) != 0 || len (plan .triggers ) != 0 {
@@ -5298,82 +5298,76 @@ func checkScanParallelizationIfLocal(
5298
5298
// the scan parallelization.
5299
5299
return true , false
5300
5300
}
5301
- * c = localScanParallelizationChecker {}
5302
- o := planObserver {enterNode : c .enterNode }
5303
- _ = walkPlan (ctx , plan .main .planNode , o )
5304
- for _ , s := range plan .subqueryPlans {
5305
- _ = walkPlan (ctx , s .plan .planNode , o )
5306
- }
5307
- return c .prohibitParallelization , c .hasScanNodeToParallelize
5308
- }
5309
-
5310
- type localScanParallelizationChecker struct {
5311
- prohibitParallelization bool
5312
- hasScanNodeToParallelize bool
5313
- }
5314
5301
5315
- func (c * localScanParallelizationChecker ) enterNode (
5316
- ctx context.Context , _ string , plan planNode ,
5317
- ) (bool , error ) {
5318
- if c .prohibitParallelization {
5319
- return false , nil
5320
- }
5321
- switch n := plan .(type ) {
5322
- case * distinctNode :
5323
- return true , nil
5324
- case * explainPlanNode :
5325
- // walkPlan doesn't recurse into explainPlanNode, so we have to manually
5326
- // walk over the wrapped plan.
5327
- plan := n .plan .WrappedPlan .(* planComponents )
5328
- prohibit , has := checkScanParallelizationIfLocal (ctx , plan , c )
5329
- c .prohibitParallelization = c .prohibitParallelization || prohibit
5330
- c .hasScanNodeToParallelize = c .hasScanNodeToParallelize || has
5331
- return false , nil
5332
- case * explainVecNode :
5333
- return true , nil
5334
- case * filterNode :
5335
- // Some filter expressions might be handled by falling back to the
5336
- // wrapped processors, so we choose to be safe.
5337
- c .prohibitParallelization = true
5338
- return false , nil
5339
- case * groupNode :
5340
- for _ , f := range n .funcs {
5341
- c .prohibitParallelization = f .hasFilter ()
5302
+ var checkRec func (p planNode )
5303
+ checkRec = func (p planNode ) {
5304
+ if prohibitParallelization {
5305
+ return
5342
5306
}
5343
- return true , nil
5344
- case * indexJoinNode :
5345
- return true , nil
5346
- case * joinNode :
5347
- c .prohibitParallelization = n .pred .onCond != nil
5348
- return true , nil
5349
- case * limitNode :
5350
- return true , nil
5351
- case * ordinalityNode :
5352
- return true , nil
5353
- case * renderNode :
5354
- // Only support projections since render expressions might be handled
5355
- // via a wrapped row-by-row processor.
5356
- for _ , e := range n .render {
5357
- if _ , isIVar := e .(* tree.IndexedVar ); ! isIVar {
5358
- c .prohibitParallelization = true
5307
+ switch n := p .(type ) {
5308
+ case * explainPlanNode :
5309
+ // explainPlanNode is a zeroInputPlanNode, so we have to manually
5310
+ // recurse.
5311
+ plan := n .plan .WrappedPlan .(* planComponents )
5312
+ prohibit , has := checkScanParallelizationIfLocal (ctx , plan )
5313
+ prohibitParallelization = prohibitParallelization || prohibit
5314
+ hasScanNodeToParallelize = hasScanNodeToParallelize || has
5315
+ // Do not recurse.
5316
+ return
5317
+ case * filterNode :
5318
+ // Some filter expressions might be handled by falling back to the
5319
+ // wrapped processors, so we choose to be safe.
5320
+ prohibitParallelization = true
5321
+ // Do not recurse.
5322
+ return
5323
+ case * groupNode :
5324
+ for _ , f := range n .funcs {
5325
+ if f .hasFilter () {
5326
+ prohibitParallelization = true
5327
+ // Do not recurse.
5328
+ return
5329
+ }
5330
+ }
5331
+ case * joinNode :
5332
+ prohibitParallelization = n .pred .onCond != nil
5333
+ case * renderNode :
5334
+ // Only support projections since render expressions might be
5335
+ // handled via a wrapped row-by-row processor.
5336
+ for _ , e := range n .render {
5337
+ if _ , isIVar := e .(* tree.IndexedVar ); ! isIVar {
5338
+ prohibitParallelization = true
5339
+ // Do not recurse.
5340
+ return
5341
+ }
5359
5342
}
5343
+ case * scanNode :
5344
+ if len (n .reqOrdering ) == 0 && n .parallelize {
5345
+ hasScanNodeToParallelize = true
5346
+ }
5347
+ case * distinctNode , * explainVecNode , * indexJoinNode , * limitNode ,
5348
+ * ordinalityNode , * sortNode , * unionNode , * valuesNode :
5349
+ default :
5350
+ prohibitParallelization = true
5351
+ // Do not recurse into any unmatched nodes.
5352
+ return
5360
5353
}
5361
- return true , nil
5362
- case * scanNode :
5363
- if len (n .reqOrdering ) == 0 && n .parallelize {
5364
- c .hasScanNodeToParallelize = true
5354
+ // Recurse into input nodes.
5355
+ for i , n := 0 , p .InputCount (); i < n ; i ++ {
5356
+ input , err := p .Input (i )
5357
+ if err != nil {
5358
+ // This error should never occur with correct usage of Input
5359
+ // and InputCount. If it does, ignore it and prohibit
5360
+ // parallelization.
5361
+ prohibitParallelization = true
5362
+ }
5363
+ checkRec (input )
5365
5364
}
5366
- return true , nil
5367
- case * sortNode :
5368
- return true , nil
5369
- case * unionNode :
5370
- return true , nil
5371
- case * valuesNode :
5372
- return true , nil
5373
- default :
5374
- c .prohibitParallelization = true
5375
- return false , nil
5376
5365
}
5366
+ checkRec (plan .main .planNode )
5367
+ for _ , s := range plan .subqueryPlans {
5368
+ checkRec (s .plan .planNode )
5369
+ }
5370
+ return prohibitParallelization , hasScanNodeToParallelize
5377
5371
}
5378
5372
5379
5373
// NewPlanningCtx returns a new PlanningCtx. When distribute is false, a
@@ -5435,7 +5429,7 @@ func (dsp *DistSQLPlanner) NewPlanningCtxWithOracle(
5435
5429
return planCtx
5436
5430
}
5437
5431
prohibitParallelization , hasScanNodeToParallelize := checkScanParallelizationIfLocal (
5438
- ctx , & planner .curPlan .planComponents , & planner . parallelizationChecker ,
5432
+ ctx , & planner .curPlan .planComponents ,
5439
5433
)
5440
5434
if prohibitParallelization || ! hasScanNodeToParallelize {
5441
5435
return planCtx
0 commit comments