Skip to content

fix: Do not add redundant exchange over remote function#27170

Merged
feilong-liu merged 1 commit intoprestodb:masterfrom
feilong-liu:export-D93701641
Feb 23, 2026
Merged

fix: Do not add redundant exchange over remote function#27170
feilong-liu merged 1 commit intoprestodb:masterfrom
feilong-liu:export-D93701641

Conversation

@feilong-liu
Copy link
Copy Markdown
Contributor

@feilong-liu feilong-liu commented Feb 19, 2026

Description

We added an option in #27044 to set the number of tasks for remote functions, however we observe that it will add an unnecessary exchange even when the remote function directly send data to output node. This PR will remove this unnecessary exchange node.

Motivation and Context

Simplify plans

Impact

Make the plan to streaming result out.

Test Plan

Unit tests

Contributor checklist

  • Please make sure your submission complies with our contributing guide, in particular code style and commit standards.
  • PR description addresses the issue accurately and concisely. If the change is non-trivial, a GitHub Issue is referenced.
  • Documented new properties (with its default value), SQL syntax, functions, or other functionality.
  • If release notes are required, they follow the release notes guidelines.
  • Adequate tests were added if applicable.
  • CI passed.
  • If adding new dependencies, verified they have an OpenSSF Scorecard score of 5.0 or higher (or obtained explicit TSC approval for lower scores).

Release Notes

Please follow release notes guidelines and fill in the release notes below.

== NO RELEASE NOTE ==

Summary by Sourcery

Adjust exchange planning for remote function projections to avoid adding unnecessary trailing exchanges when the plan is not required to be distributed.

Bug Fixes:

  • Prevent insertion of a redundant trailing remote exchange for fixed-parallelism remote function projections when the preferred global properties are undistributed.

Tests:

  • Update existing remote function fixed-parallelism plan tests to expect a gather exchange at the root where appropriate.
  • Add tests covering when trailing exchanges are skipped or preserved for remote function projections under undistributed vs distributed plans.

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai bot commented Feb 19, 2026

Reviewer's Guide

Updates AddExchanges so it only adds a trailing remote round‑robin exchange for remote fixed‑parallelism projections when the preferred global properties are distributed, and adjusts/extends planner tests to assert the new behavior for both distributed and undistributed cases.

Sequence diagram for AddExchanges conditional trailing exchange on ProjectNode

sequenceDiagram
    participant Planner as Planner
    participant AddExchanges as AddExchanges
    participant PreferredProperties as PreferredProperties
    participant GlobalProps as GlobalProperties

    Planner->>AddExchanges: visitProject(projectNode, preferredProperties)
    AddExchanges->>AddExchanges: create first remote roundRobinExchange
    AddExchanges->>AddExchanges: replace ProjectNode child with first exchange

    AddExchanges->>PreferredProperties: getGlobalProperties()
    PreferredProperties-->>AddExchanges: Optional<GlobalProperties>
    AddExchanges->>GlobalProps: isDistributed()
    GlobalProps-->>AddExchanges: boolean

    alt distributed or absent (default true)
        AddExchanges->>AddExchanges: create trailing remote roundRobinExchange
        AddExchanges-->>Planner: PlanWithProperties(ProjectNode + two exchanges)
    else undistributed
        AddExchanges-->>Planner: PlanWithProperties(ProjectNode + one exchange)
    end
Loading

File-Level Changes

Change Details Files
Gate the addition of the final remote round-robin exchange behind a distributed-preference check in AddExchanges.
  • After building the fixed-parallelism remote round-robin exchange for a ProjectNode, only add the final REMOTE_STREAMING round-robin exchange when PreferredProperties.global is distributed or unspecified (default true).
  • Leave the existing behavior unchanged for distributed plans while skipping the extra exchange for undistributed plans, which makes the output stage undistributed in those cases.
presto-main-base/src/main/java/com/facebook/presto/sql/planner/optimizations/AddExchanges.java
Align and extend AddExchanges planner tests to the new exchange behavior for remote functions with fixed parallelism.
  • Change expected top-level exchange in several existing remote fixed-parallelism tests from REMOTE_STREAMING REPARTITION to REMOTE_STREAMING GATHER, reflecting the removal of the extra repartitioning exchange at the root.
  • Add a test that verifies the trailing exchange is skipped when the plan is undistributed and both LIMIT and non-LIMIT queries use a GATHER root exchange over a remote projection.
  • Add a complementary test ensuring the trailing exchange is not skipped for distributed queries (e.g., DISTINCT + LIMIT) and the plan still includes a REPARTITION exchange above the remote projection.
  • Keep other test scaffolding (session properties, projections, scans) consistent so only the shape and distribution of the exchange nodes change.
presto-main-base/src/test/java/com/facebook/presto/sql/planner/optimizations/TestAddExchangesPlansWithFunctions.java

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@feilong-liu feilong-liu changed the title Do not add exchange when outputting results fix: do not add redundant exchange over remote function Feb 19, 2026
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • In AddExchanges.visitProject, the new condition uses preferredProperties.getGlobalProperties().map(PreferredProperties.Global::isDistributed).orElse(true); consider whether orElse(true) is really desired (i.e., defaulting to adding the trailing exchange when distribution is unknown) or if defaulting to false would better reflect the intended behavior.
  • The two new tests for skipping vs not skipping the trailing exchange build the same session configuration multiple times; consider extracting a small helper to construct that session to keep the tests more focused on the query shape and expected plan.
  • The method name testRemoteFunctionFixedParallelismNotSkipsTrailingExchangeWhenDistributed is a bit hard to parse; renaming to something like testRemoteFunctionFixedParallelismKeepsTrailingExchangeWhenDistributed would make the intent clearer.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `AddExchanges.visitProject`, the new condition uses `preferredProperties.getGlobalProperties().map(PreferredProperties.Global::isDistributed).orElse(true)`; consider whether `orElse(true)` is really desired (i.e., defaulting to adding the trailing exchange when distribution is unknown) or if defaulting to `false` would better reflect the intended behavior.
- The two new tests for skipping vs not skipping the trailing exchange build the same session configuration multiple times; consider extracting a small helper to construct that session to keep the tests more focused on the query shape and expected plan.
- The method name `testRemoteFunctionFixedParallelismNotSkipsTrailingExchangeWhenDistributed` is a bit hard to parse; renaming to something like `testRemoteFunctionFixedParallelismKeepsTrailingExchangeWhenDistributed` would make the intent clearer.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@feilong-liu feilong-liu changed the title fix: do not add redundant exchange over remote function fix: Do not add redundant exchange over remote function Feb 19, 2026
@kaikalur
Copy link
Copy Markdown
Contributor

Actually, it should never be needed because if the next stage needs exchange, it will be done automatically.

Summary:

As title

Differential Revision: D93701641
@feilong-liu
Copy link
Copy Markdown
Contributor Author

Actually, it should never be needed because if the next stage needs exchange, it will be done automatically.

You are right, we do not need this additional exchange. Updated the code

@feilong-liu feilong-liu merged commit 25baa62 into prestodb:master Feb 23, 2026
111 of 112 checks passed
@feilong-liu feilong-liu deleted the export-D93701641 branch February 23, 2026 17:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants