@@ -325,11 +325,17 @@ set_dummy_rel_pathlist(RelOptInfo *rel)
325
325
* If this relation could possibly be scanned from within a worker, then set
326
326
* its consider_parallel flag.
327
327
*/
328
- #if PG_VERSION_NUM >= 100000
329
328
void
330
329
set_rel_consider_parallel (PlannerInfo * root , RelOptInfo * rel ,
331
330
RangeTblEntry * rte )
332
331
{
332
+ #if PG_VERSION_NUM >= 100000
333
+ #define is_parallel_safe_compat (root , exprs ) is_parallel_safe((root), (exprs))
334
+ #elif PG_VERSION_NUM >= 90500
335
+ #define is_parallel_safe_compat (root , exprs ) \
336
+ (!has_parallel_hazard((exprs), false))
337
+ #endif
338
+
333
339
/*
334
340
* The flag has previously been initialized to false, so we can just
335
341
* return if it becomes clear that we can't safely set it.
@@ -340,7 +346,8 @@ set_rel_consider_parallel(PlannerInfo *root, RelOptInfo *rel,
340
346
Assert (root -> glob -> parallelModeOK );
341
347
342
348
/* This should only be called for baserels and appendrel children. */
343
- Assert (IS_SIMPLE_REL (rel ));
349
+ Assert (rel -> reloptkind == RELOPT_BASEREL ||
350
+ rel -> reloptkind == RELOPT_OTHER_MEMBER_REL );
344
351
345
352
/* Assorted checks based on rtekind. */
346
353
switch (rte -> rtekind )
@@ -370,7 +377,8 @@ set_rel_consider_parallel(PlannerInfo *root, RelOptInfo *rel,
370
377
371
378
if (proparallel != PROPARALLEL_SAFE )
372
379
return ;
373
- if (!is_parallel_safe (root , (Node * ) rte -> tablesample -> args ))
380
+ if (!is_parallel_safe_compat (
381
+ root , (Node * ) rte -> tablesample -> args ))
374
382
return ;
375
383
}
376
384
@@ -423,17 +431,19 @@ set_rel_consider_parallel(PlannerInfo *root, RelOptInfo *rel,
423
431
424
432
case RTE_FUNCTION :
425
433
/* Check for parallel-restricted functions. */
426
- if (!is_parallel_safe (root , (Node * ) rte -> functions ))
434
+ if (!is_parallel_safe_compat (root , (Node * ) rte -> functions ))
427
435
return ;
428
436
break ;
429
437
438
+ #if PG_VERSION_NUM >= 100000
430
439
case RTE_TABLEFUNC :
431
440
/* not parallel safe */
432
441
return ;
442
+ #endif
433
443
434
444
case RTE_VALUES :
435
445
/* Check for parallel-restricted functions. */
436
- if (!is_parallel_safe (root , (Node * ) rte -> values_lists ))
446
+ if (!is_parallel_safe_compat (root , (Node * ) rte -> values_lists ))
437
447
return ;
438
448
break ;
439
449
@@ -448,12 +458,14 @@ set_rel_consider_parallel(PlannerInfo *root, RelOptInfo *rel,
448
458
*/
449
459
return ;
450
460
461
+ #if PG_VERSION_NUM >= 100000
451
462
case RTE_NAMEDTUPLESTORE :
452
463
/*
453
464
* tuplestore cannot be shared, at least without more
454
465
* infrastructure to support that.
455
466
*/
456
467
return ;
468
+ #endif
457
469
}
458
470
459
471
/*
@@ -465,164 +477,19 @@ set_rel_consider_parallel(PlannerInfo *root, RelOptInfo *rel,
465
477
* outer join clauses work correctly. It would likely break equivalence
466
478
* classes, too.
467
479
*/
468
- if (!is_parallel_safe (root , (Node * ) rel -> baserestrictinfo ))
469
- return ;
470
-
471
- /*
472
- * Likewise, if the relation's outputs are not parallel-safe, give up.
473
- * (Usually, they're just Vars, but sometimes they're not.)
474
- */
475
- if (!is_parallel_safe (root , (Node * ) rel -> reltarget -> exprs ))
476
- return ;
477
-
478
- /* We have a winner. */
479
- rel -> consider_parallel = true;
480
- }
481
- #elif PG_VERSION_NUM >= 90600
482
- void
483
- set_rel_consider_parallel (PlannerInfo * root , RelOptInfo * rel ,
484
- RangeTblEntry * rte )
485
- {
486
- /*
487
- * The flag has previously been initialized to false, so we can just
488
- * return if it becomes clear that we can't safely set it.
489
- */
490
- Assert (!rel -> consider_parallel );
491
-
492
- /* Don't call this if parallelism is disallowed for the entire query. */
493
- Assert (root -> glob -> parallelModeOK );
494
-
495
- /* This should only be called for baserels and appendrel children. */
496
- Assert (rel -> reloptkind == RELOPT_BASEREL ||
497
- rel -> reloptkind == RELOPT_OTHER_MEMBER_REL );
498
-
499
- /* Assorted checks based on rtekind. */
500
- switch (rte -> rtekind )
501
- {
502
- case RTE_RELATION :
503
-
504
- /*
505
- * Currently, parallel workers can't access the leader's temporary
506
- * tables. We could possibly relax this if the wrote all of its
507
- * local buffers at the start of the query and made no changes
508
- * thereafter (maybe we could allow hint bit changes), and if we
509
- * taught the workers to read them. Writing a large number of
510
- * temporary buffers could be expensive, though, and we don't have
511
- * the rest of the necessary infrastructure right now anyway. So
512
- * for now, bail out if we see a temporary table.
513
- */
514
- if (get_rel_persistence (rte -> relid ) == RELPERSISTENCE_TEMP )
515
- return ;
516
-
517
- /*
518
- * Table sampling can be pushed down to workers if the sample
519
- * function and its arguments are safe.
520
- */
521
- if (rte -> tablesample != NULL )
522
- {
523
- char proparallel = func_parallel (rte -> tablesample -> tsmhandler );
524
-
525
- if (proparallel != PROPARALLEL_SAFE )
526
- return ;
527
- if (has_parallel_hazard ((Node * ) rte -> tablesample -> args ,
528
- false))
529
- return ;
530
- }
531
-
532
- /*
533
- * Ask FDWs whether they can support performing a ForeignScan
534
- * within a worker. Most often, the answer will be no. For
535
- * example, if the nature of the FDW is such that it opens a TCP
536
- * connection with a remote server, each parallel worker would end
537
- * up with a separate connection, and these connections might not
538
- * be appropriately coordinated between workers and the leader.
539
- */
540
- if (rte -> relkind == RELKIND_FOREIGN_TABLE )
541
- {
542
- Assert (rel -> fdwroutine );
543
- if (!rel -> fdwroutine -> IsForeignScanParallelSafe )
544
- return ;
545
- if (!rel -> fdwroutine -> IsForeignScanParallelSafe (root , rel , rte ))
546
- return ;
547
- }
548
-
549
- /*
550
- * There are additional considerations for appendrels, which we'll
551
- * deal with in set_append_rel_size and set_append_rel_pathlist.
552
- * For now, just set consider_parallel based on the rel's own
553
- * quals and targetlist.
554
- */
555
- break ;
556
-
557
- case RTE_SUBQUERY :
558
-
559
- /*
560
- * There's no intrinsic problem with scanning a subquery-in-FROM
561
- * (as distinct from a SubPlan or InitPlan) in a parallel worker.
562
- * If the subquery doesn't happen to have any parallel-safe paths,
563
- * then flagging it as consider_parallel won't change anything,
564
- * but that's true for plain tables, too. We must set
565
- * consider_parallel based on the rel's own quals and targetlist,
566
- * so that if a subquery path is parallel-safe but the quals and
567
- * projection we're sticking onto it are not, we correctly mark
568
- * the SubqueryScanPath as not parallel-safe. (Note that
569
- * set_subquery_pathlist() might push some of these quals down
570
- * into the subquery itself, but that doesn't change anything.)
571
- */
572
- break ;
573
-
574
- case RTE_JOIN :
575
- /* Shouldn't happen; we're only considering baserels here. */
576
- Assert (false);
577
- return ;
578
-
579
- case RTE_FUNCTION :
580
- /* Check for parallel-restricted functions. */
581
- if (has_parallel_hazard ((Node * ) rte -> functions , false))
582
- return ;
583
- break ;
584
-
585
- case RTE_VALUES :
586
- /* Check for parallel-restricted functions. */
587
- if (has_parallel_hazard ((Node * ) rte -> values_lists , false))
588
- return ;
589
- break ;
590
-
591
- case RTE_CTE :
592
-
593
- /*
594
- * CTE tuplestores aren't shared among parallel workers, so we
595
- * force all CTE scans to happen in the leader. Also, populating
596
- * the CTE would require executing a subplan that's not available
597
- * in the worker, might be parallel-restricted, and must get
598
- * executed only once.
599
- */
600
- return ;
601
- }
602
-
603
- /*
604
- * If there's anything in baserestrictinfo that's parallel-restricted, we
605
- * give up on parallelizing access to this relation. We could consider
606
- * instead postponing application of the restricted quals until we're
607
- * above all the parallelism in the plan tree, but it's not clear that
608
- * that would be a win in very many cases, and it might be tricky to make
609
- * outer join clauses work correctly. It would likely break equivalence
610
- * classes, too.
611
- */
612
- if (has_parallel_hazard ((Node * ) rel -> baserestrictinfo , false))
480
+ if (!is_parallel_safe_compat (root , (Node * ) rel -> baserestrictinfo ))
613
481
return ;
614
482
615
483
/*
616
484
* Likewise, if the relation's outputs are not parallel-safe, give up.
617
485
* (Usually, they're just Vars, but sometimes they're not.)
618
486
*/
619
- if (has_parallel_hazard ( (Node * ) rel -> reltarget -> exprs , false ))
487
+ if (! is_parallel_safe_compat ( root , (Node * ) rel -> reltarget -> exprs ))
620
488
return ;
621
489
622
490
/* We have a winner. */
623
491
rel -> consider_parallel = true;
624
492
}
625
- #endif
626
493
627
494
628
495
/*
0 commit comments