Hi,

Yet another thing I noticed while working on [1] is this in
grouping_planner:

    /*
     * If the input rel is marked consider_parallel and there's nothing
that's
     * not parallel-safe in the LIMIT clause, then the final_rel can be
marked
     * consider_parallel as well.  Note that if the query has rowMarks or is
     * not a SELECT, consider_parallel will be false for every relation
in the
     * query.
     */
    if (current_rel->consider_parallel &&
        is_parallel_safe(root, parse->limitOffset) &&
        is_parallel_safe(root, parse->limitCount))
        final_rel->consider_parallel = true;

If there is a need to add a LIMIT node, we don't consider generating
partial paths for the final relation below (see commit
0927d2f46ddd4cf7d6bf2cc84b3be923e0aedc52), so it seems unnecessary
anymore to assess the parallel-safety of the LIMIT and OFFSET clauses.
To save cycles, why not remove those tests from that function like the
attached?

Best regards,
Etsuro Fujita

[1] https://commitfest.postgresql.org/22/1950/
*** a/src/backend/optimizer/plan/planner.c
--- b/src/backend/optimizer/plan/planner.c
***************
*** 2141,2155 **** grouping_planner(PlannerInfo *root, bool inheritance_update,
  	final_rel = fetch_upper_rel(root, UPPERREL_FINAL, NULL);
  
  	/*
! 	 * If the input rel is marked consider_parallel and there's nothing that's
! 	 * not parallel-safe in the LIMIT clause, then the final_rel can be marked
! 	 * consider_parallel as well.  Note that if the query has rowMarks or is
! 	 * not a SELECT, consider_parallel will be false for every relation in the
! 	 * query.
  	 */
! 	if (current_rel->consider_parallel &&
! 		is_parallel_safe(root, parse->limitOffset) &&
! 		is_parallel_safe(root, parse->limitCount))
  		final_rel->consider_parallel = true;
  
  	/*
--- 2141,2152 ----
  	final_rel = fetch_upper_rel(root, UPPERREL_FINAL, NULL);
  
  	/*
! 	 * If the input rel is marked consider_parallel and there's no need to add
! 	 * a LIMIT node, then the final_rel can be marked consider_parallel as
! 	 * well.  Note that if the query has rowMarks or is not a SELECT,
! 	 * consider_parallel will be false for every relation in the query.
  	 */
! 	if (current_rel->consider_parallel && !limit_needed(parse))
  		final_rel->consider_parallel = true;
  
  	/*
***************
*** 2263,2272 **** grouping_planner(PlannerInfo *root, bool inheritance_update,
  	 * Generate partial paths for final_rel, too, if outer query levels might
  	 * be able to make use of them.
  	 */
! 	if (final_rel->consider_parallel && root->query_level > 1 &&
! 		!limit_needed(parse))
  	{
! 		Assert(!parse->rowMarks && parse->commandType == CMD_SELECT);
  		foreach(lc, current_rel->partial_pathlist)
  		{
  			Path	   *partial_path = (Path *) lfirst(lc);
--- 2260,2269 ----
  	 * Generate partial paths for final_rel, too, if outer query levels might
  	 * be able to make use of them.
  	 */
! 	if (final_rel->consider_parallel && root->query_level > 1)
  	{
! 		Assert(!parse->rowMarks && !limit_needed(parse) &&
! 			   parse->commandType == CMD_SELECT);
  		foreach(lc, current_rel->partial_pathlist)
  		{
  			Path	   *partial_path = (Path *) lfirst(lc);

Reply via email to