Skip to content

Conversation

kasiafi
Copy link
Member

@kasiafi kasiafi commented Oct 14, 2025

Description

The change makes the query under ExplainAnalyzeNode plan the same way as under OutputNode.
Example query that has different plan shape before this change:

EXPLAIN ANALYZE
SELECT * FROM
(SELECT * from nation n, region r WHERE n.regionkey = 1 AND r.regionkey = 1)
UNION ALL
(SELECT * from nation n, region r WHERE n.regionkey = 1 AND r.regionkey = 1);

Additional context and related issues

Release notes

( ) This is not user-visible or is docs only, and no release notes are required.
( ) Release notes are required. Please propose a release note for me.
(X) Release notes are required, with the following suggested text:

## General
* Ensure that queries with and without EXPLAIN ANALYZE are planned in the same way. ({issue}`26938`)

Summary by Sourcery

Unify query planning for EXPLAIN ANALYZE and regular queries by using undistributed preferred properties and always adding a gathering exchange, and expand test coverage to validate plan consistency across TPC-H and TPC-DS suites.

Enhancements:

  • Generate EXPLAIN ANALYZE plans with the same distribution properties as regular output plans
  • Always insert a gathering exchange for ExplainAnalyze nodes to ensure they run in their own stage

Tests:

  • Add assertExplainAnalyzePlan utility to compare plans with and without EXPLAIN ANALYZE
  • Add parameterized tests for EXPLAIN ANALYZE on TPC-H and TPC-DS benchmark queries
  • Extend TestLogicalPlanner to verify distributed planning of EXPLAIN ANALYZE with UNION ALL

@cla-bot cla-bot bot added the cla-signed label Oct 14, 2025
Copy link

sourcery-ai bot commented Oct 14, 2025

Reviewer's Guide

This PR ensures that EXPLAIN ANALYZE queries are planned the same way as regular queries by normalizing the additional ExplainAnalyze wrapper and top-level exchanges, refactors AddExchanges to always introduce a gathering exchange with undistributed properties for ExplainAnalyzeNode, and strengthens coverage with new parameterized tests for TPCH and TPCDS workloads.

Class diagram for AddExchanges changes (ExplainAnalyzeNode planning)

classDiagram
    class AddExchanges {
        +visitExplainAnalyze(node, preferredProperties)
    }
    class ExplainAnalyzeNode
    class ExchangeNode {
        +Type: enum {GATHER, ...}
    }
    class PlanWithProperties {
        +getNode()
    }
    AddExchanges --> ExplainAnalyzeNode
    AddExchanges --> ExchangeNode
    AddExchanges --> PlanWithProperties
    ExplainAnalyzeNode <|-- ExchangeNode
    PlanWithProperties --> ExchangeNode
    AddExchanges : planChild(node, PreferredProperties.undistributed())
    AddExchanges : Always add gathering ExchangeNode for ExplainAnalyzeNode
Loading

File-Level Changes

Change Details Files
Introduce assertExplainAnalyzePlan in test harness
  • Add method to compare EXPLAIN ANALYZE plan to regular plan (stripping top two lines and adjusting indentation)
  • Reuse generateQueryPlan for both variants
  • Split and reassemble plan text for comparison
BaseCostBasedPlanTest.java
Refactor AddExchanges for ExplainAnalyzeNode
  • Remove existing gathering-exchange check
  • Always plan child with PreferredProperties.undistributed()
  • Introduce an explicit gathering exchange to isolate ExplainAnalyze stage
AddExchanges.java
Extend logical planner tests for EXPLAIN ANALYZE
  • Add assertDistributedPlan call in TestLogicalPlanner.testExplainAnalyze
  • Verify nested exchanges on UNION ALL under EXPLAIN ANALYZE
TestLogicalPlanner.java
Add new parameterized tests for TPCH and TPCDS plans under EXPLAIN ANALYZE
  • Create TestExplainAnalyzeTpchPlan for unpartitioned TPCH
  • Create TestExplainAnalyzePartitionedTpcdsPlan for partitioned TPCDS
  • Override test harness methods to point at workload-specific resources
TestExplainAnalyzeTpchPlan.java
TestExplainAnalyzePartitionedTpcdsPlan.java

Possibly linked issues

  • #the issue: The PR modifies how Explain Analyze queries are planned, which resolves the IllegalStateException encountered with TableExecute.

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

Copy link

@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 there - I've reviewed your changes - here's some feedback:

  • The indentation stripping in assertExplainAnalyzePlan relies on exactly eight spaces and two header lines; consider computing the common indent and header length dynamically to make the test resilient to formatting changes.
  • The two TestExplainAnalyze*Plan classes share almost identical logic except for table sources—consider parameterizing or consolidating them to reduce duplication.
  • Removing the special-case check for existing gathering exchanges in AddExchanges may introduce redundant exchanges for ExplainAnalyze; ensure this change doesn’t inadvertently produce extra exchange nodes.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The indentation stripping in assertExplainAnalyzePlan relies on exactly eight spaces and two header lines; consider computing the common indent and header length dynamically to make the test resilient to formatting changes.
- The two TestExplainAnalyze*Plan classes share almost identical logic except for table sources—consider parameterizing or consolidating them to reduce duplication.
- Removing the special-case check for existing gathering exchanges in AddExchanges may introduce redundant exchanges for ExplainAnalyze; ensure this change doesn’t inadvertently produce extra exchange nodes.

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.

@findepi
Copy link
Member

findepi commented Oct 15, 2025

@kasiafi kasiafi merged commit 9ab4eae into trinodb:master Oct 15, 2025
97 checks passed
@github-actions github-actions bot added this to the 478 milestone Oct 15, 2025
@ebyhr
Copy link
Member

ebyhr commented Oct 16, 2025

@kasiafi Could you update "Release notes" section?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

6 participants