Skip to content

misc: Move TopNRowNumberNode to presto-spi for connector optimizer access#27232

Merged
feilong-liu merged 1 commit intoprestodb:masterfrom
feilong-liu:export-D94627414
Feb 27, 2026
Merged

misc: Move TopNRowNumberNode to presto-spi for connector optimizer access#27232
feilong-liu merged 1 commit intoprestodb:masterfrom
feilong-liu:export-D94627414

Conversation

@feilong-liu
Copy link
Copy Markdown
Contributor

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

Description

Similar to changes in #24088

Summary:
Move TopNRowNumberNode from presto-main-base to presto-spi to make it
accessible to connector optimizers in ApplyConnectorOptimization.java.

Changes:

  • Move TopNRowNumberNode.java to presto-spi/src/main/java/com/facebook/presto/spi/plan/
  • Change extends InternalPlanNode to extends PlanNode
  • Add visitTopNRowNumber to PlanVisitor.java
  • Remove visitTopNRowNumber from InternalPlanVisitor.java
  • Add TopNRowNumberNode to CONNECTOR_ACCESSIBLE_PLAN_NODES
  • Update all imports across the codebase
  • Update protocol YAML files to use .TopNRowNumberNode key
  • Regenerate C++ protocol files

Differential Revision: D94627414

Motivation and Context

As in description

Impact

As in description

Test Plan

Existing unit tests

== NO RELEASE NOTE ==

Summary by Sourcery

Expose TopNRowNumberNode as a connector-accessible SPI plan node and align protocol/serialization support.

Enhancements:

  • Move TopNRowNumberNode from presto-main-base into presto-spi as a PlanNode with a PlanVisitor hook so connector optimizers can see and transform it.
  • Tighten TopNRowNumberNode child handling and output variable construction using standard collections utilities instead of Guava.
  • Add a catchableByTry field to ErrorCode in the native protocol to support JSON round-tripping.

Build:

  • Update Java/C++ protocol YAML mappings and generated native protocol code to use the shortened .TopNRowNumberNode type key instead of the old fully qualified class name.

@feilong-liu feilong-liu requested review from a team, elharo and jaystarshot as code owners February 27, 2026 06:26
@prestodb-ci prestodb-ci added the from:Meta PR from Meta label Feb 27, 2026
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai bot commented Feb 27, 2026

Reviewer's Guide

TopNRowNumberNode is moved into presto-spi and made a connector-accessible PlanNode, with corresponding visitor, optimizer, serialization, and native protocol updates to treat it like other SPI plan nodes and a small behavior tweak in replaceChildren/getOutputVariables.

Sequence diagram for TopNRowNumberNode JSON protocol between Java and C++

sequenceDiagram
    participant PlannerJava as PlannerJava
    participant JsonSer as JavaJsonSerializer
    participant CppProtocol as CppProtocol
    participant NativeExec as NativeExecutionEngine

    PlannerJava->>JsonSer: serialize PlanNode tree
    JsonSer->>JsonSer: detect TopNRowNumberNode
    JsonSer->>JsonSer: set _type and @type to .TopNRowNumberNode
    JsonSer-->>CppProtocol: JSON plan

    CppProtocol->>CppProtocol: read @type field
    CppProtocol->>CppProtocol: if type == .TopNRowNumberNode
    CppProtocol->>CppProtocol: construct TopNRowNumberNode
    CppProtocol->>CppProtocol: from_json populate fields

    CppProtocol-->>NativeExec: TopNRowNumberNode instance
    NativeExec->>NativeExec: execute plan with TopNRowNumberNode
Loading

Class diagram for SPI PlanNode hierarchy and TopNRowNumberNode move

classDiagram
    class PlanNode {
      +PlanNodeId id
      +SourceLocation sourceLocation
      +PlanNode getStatsEquivalentPlanNode()
      +List~PlanNode~ getSources()
      +List~VariableReferenceExpression~ getOutputVariables()
      +PlanNode replaceChildren(List~PlanNode~ newChildren)
      +R accept(PlanVisitor~R, C~ visitor, C context)
    }

    class InternalPlanNode {
      +PlanNodeId id
      +SourceLocation sourceLocation
      +PlanNode getStatsEquivalentPlanNode()
      +List~PlanNode~ getSources()
      +List~VariableReferenceExpression~ getOutputVariables()
      +PlanNode replaceChildren(List~PlanNode~ newChildren)
      +R accept(InternalPlanVisitor~R, C~ visitor, C context)
    }

    class TopNRowNumberNode {
      +RankingFunction rankingFunction
      +DataOrganizationSpecification specification
      +VariableReferenceExpression rowNumberVariable
      +Optional~VariableReferenceExpression~ hashVariable
      +long maxRowCountPerPartition
      +boolean partial
      +PlanNode source
      +List~PlanNode~ getSources()
      +List~VariableReferenceExpression~ getOutputVariables()
      +Optional~VariableReferenceExpression~ getHashVariable()
      +PlanNode replaceChildren(List~PlanNode~ newChildren)
      +R accept(PlanVisitor~R, C~ visitor, C context)
    }

    class RankingFunction {
      <<enum>>
      DENSE_RANK
      RANK
      ROW_NUMBER
    }

    class PlanVisitor~R, C~ {
      +R visitPlan(PlanNode node, C context)
      +R visitTopNRowNumber(TopNRowNumberNode node, C context)
      +R visitMaterializedViewScan(MaterializedViewScanNode node, C context)
      %% other visit methods for connector accessible nodes
    }

    class InternalPlanVisitor~R, C~ {
      +R visitPlan(PlanNode node, C context)
      +R visitRowNumber(RowNumberNode node, C context)
      +R visitExchange(ExchangeNode node, C context)
      %% no visitTopNRowNumber here after the change
    }

    class ApplyConnectorOptimization {
      -Set~Class~ connectorAccessiblePlanNodes
      +PlanNode optimize(PlanNode root)
    }

    PlanNode <|-- InternalPlanNode
    PlanNode <|-- TopNRowNumberNode

    RankingFunction <.. TopNRowNumberNode
    DataOrganizationSpecification <.. TopNRowNumberNode
    VariableReferenceExpression <.. TopNRowNumberNode

    PlanVisitor <.. TopNRowNumberNode
    InternalPlanVisitor <.. InternalPlanNode

    PlanVisitor ..> TopNRowNumberNode : visitTopNRowNumber

    ApplyConnectorOptimization ..> PlanNode : uses
    ApplyConnectorOptimization ..> TopNRowNumberNode : in CONNECTOR_ACCESSIBLE_PLAN_NODES
Loading

File-Level Changes

Change Details Files
Move TopNRowNumberNode into SPI and make it a standard PlanNode instead of an InternalPlanNode.
  • Change package from sql.planner.plan to spi.plan and relocate the Java source file into presto-spi.
  • Update TopNRowNumberNode to extend PlanNode instead of InternalPlanNode and switch its visitor hook from InternalPlanVisitor to PlanVisitor.
  • Replace Guava ImmutableList/Iterables usage with JDK collections utilities, including enforcing exactly one child in replaceChildren via checkArgument.
  • Use presto-common Utils.checkArgument instead of Guava Preconditions.checkArgument.
presto-main-base/src/main/java/com/facebook/presto/sql/planner/plan/TopNRowNumberNode.java
presto-spi/src/main/java/com/facebook/presto/spi/plan/TopNRowNumberNode.java
Expose TopNRowNumberNode to connector optimizers via SPI visitors and ApplyConnectorOptimization configuration.
  • Add visitTopNRowNumber to PlanVisitor so connectors can handle this node type.
  • Remove visitTopNRowNumber from InternalPlanVisitor since the node is no longer an internal-only plan node.
  • Register TopNRowNumberNode in CONNECTOR_ACCESSIBLE_PLAN_NODES in ApplyConnectorOptimization.
presto-spi/src/main/java/com/facebook/presto/spi/plan/PlanVisitor.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/plan/InternalPlanVisitor.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/optimizations/ApplyConnectorOptimization.java
Align Java/C++ protocol metadata and JSON (de)serialization for the new SPI location and type key of TopNRowNumberNode.
  • Update protocol YAML definitions to reference the new TopNRowNumberNode Java path under presto-spi and use the .TopNRowNumberNode key similar to other SPI nodes.
  • Adjust native C++ protocol to read/write TopNRowNumberNode using the new .TopNRowNumberNode type string in both constructor and JSON conversion.
  • Regenerate C++ protocol code to reflect YAML changes, including the updated TopNRowNumberNode type and minor fixes like a spelling correction in a comment.
presto-native-execution/presto_cpp/presto_protocol/core/presto_protocol_core.yml
presto-native-execution/presto_cpp/presto_protocol/presto_protocol.yml
presto-native-execution/presto_cpp/presto_protocol/core/presto_protocol_core.cpp
Extend ErrorCode protocol representation with catchableByTry flag as part of regenerated protocol bindings.
  • Add catchableByTry boolean field to ErrorCode struct in the generated C++ header.
  • Update ErrorCode JSON (de)serialization to include the catchableByTry field.
presto-native-execution/presto_cpp/presto_protocol/core/presto_protocol_core.h
presto-native-execution/presto_cpp/presto_protocol/core/presto_protocol_core.cpp
Update references and tests to the new TopNRowNumberNode package/location across the codebase.
  • Adjust Java protocol JavaClasses lists to point to the SPI TopNRowNumberNode path instead of sql.planner.plan.
  • Update imports and references in planner, optimizer, execution, and test classes to use com.facebook.presto.spi.plan.TopNRowNumberNode.
presto-native-execution/presto_cpp/presto_protocol/core/presto_protocol_core.yml
presto-native-execution/presto_cpp/presto_protocol/presto_protocol.yml
presto-hive/src/test/java/com/facebook/presto/hive/TestHiveIntegrationSmokeTest.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/CanonicalPlanGenerator.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/GroupedExecutionTagger.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/LocalExecutionPlanner.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/SplitSourceFactory.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/StatsEquivalentPlanNodeWithLimit.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/iterative/rule/MinMaxByToWindowFunction.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/iterative/rule/PushDownDereferences.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/optimizations/AddExchanges.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/optimizations/AddLocalExchanges.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/optimizations/HashGenerationOptimizer.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/optimizations/HistoricalStatisticsEquivalentPlanMarkingOptimizer.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/optimizations/KeyBasedSampler.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/optimizations/PlanNodeDecorrelator.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/optimizations/PropertyDerivations.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/optimizations/PruneUnreferencedOutputs.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/optimizations/PushdownSubfields.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/optimizations/SimplifyPlanWithEmptyInput.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/optimizations/StreamPropertyDerivations.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/optimizations/UnaliasSymbolReferences.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/optimizations/WindowFilterPushDown.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/planPrinter/PlanPrinter.java
presto-main-base/src/main/java/com/facebook/presto/sql/planner/sanity/ValidateDependenciesChecker.java
presto-main-base/src/main/java/com/facebook/presto/util/GraphvizPrinter.java
presto-main-base/src/test/java/com/facebook/presto/sql/planner/assertions/TopNRowNumberMatcher.java
presto-main-base/src/test/java/com/facebook/presto/sql/planner/optimizations/TestWindowFilterPushDown.java
presto-native-execution/src/test/java/com/facebook/presto/nativeworker/AbstractTestNativeWindowQueries.java
presto-tests/src/test/java/com/facebook/presto/execution/TestHistoryBasedStatsTracking.java
redis-hbo-provider/src/test/java/com/facebook/presto/statistic/TestHistoryBasedRedisStatisticsTracking.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

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 found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="presto-native-execution/presto_cpp/presto_protocol/core/presto_protocol_core.cpp" line_range="755" />
<code_context>
     return;
   }
-  if (type == "com.facebook.presto.sql.planner.plan.TopNRowNumberNode") {
+  if (type == ".TopNRowNumberNode") {
     j = *std::static_pointer_cast<TopNRowNumberNode>(p);
     return;
</code_context>
<issue_to_address>
**issue (bug_risk):** Changing the TopNRowNumberNode type key may break compatibility with older serialized plans.

Previously we deserialized using the FQCN key, and now we only accept the short ".TopNRowNumberNode" key. That will break deserialization for any existing persisted plans or mixed-version deployments still emitting the FQCN. If backward compatibility matters here, please either accept both keys during a transition period or clearly document this as a breaking change.
</issue_to_address>

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.

return;
}
if (type == "com.facebook.presto.sql.planner.plan.TopNRowNumberNode") {
if (type == ".TopNRowNumberNode") {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

issue (bug_risk): Changing the TopNRowNumberNode type key may break compatibility with older serialized plans.

Previously we deserialized using the FQCN key, and now we only accept the short ".TopNRowNumberNode" key. That will break deserialization for any existing persisted plans or mixed-version deployments still emitting the FQCN. If backward compatibility matters here, please either accept both keys during a transition period or clearly document this as a breaking change.

@feilong-liu feilong-liu changed the title Move TopNRowNumberNode to presto-spi for connector optimizer access misc: Move TopNRowNumberNode to presto-spi for connector optimizer access Feb 27, 2026
@feilong-liu feilong-liu requested a review from kaikalur February 27, 2026 06:29
…restodb#27232)

Summary:
Pull Request resolved: prestodb#27232

Move TopNRowNumberNode from presto-main-base to presto-spi to make it
accessible to connector optimizers in ApplyConnectorOptimization.java.

Changes:
- Move TopNRowNumberNode.java to presto-spi/src/main/java/com/facebook/presto/spi/plan/
- Change extends InternalPlanNode to extends PlanNode
- Add visitTopNRowNumber to PlanVisitor.java
- Remove visitTopNRowNumber from InternalPlanVisitor.java
- Add TopNRowNumberNode to CONNECTOR_ACCESSIBLE_PLAN_NODES
- Update all imports across the codebase
- Update protocol YAML files to use .TopNRowNumberNode key
- Regenerate C++ protocol files

Differential Revision: D94627414
@feilong-liu feilong-liu merged commit 8411757 into prestodb:master Feb 27, 2026
115 of 117 checks passed
@feilong-liu feilong-liu deleted the export-D94627414 branch February 27, 2026 19:03
feilong-liu added a commit that referenced this pull request Mar 2, 2026
…cess (#27232)

## Description

Similar to changes in #24088

Summary:
Move TopNRowNumberNode from presto-main-base to presto-spi to make it
accessible to connector optimizers in ApplyConnectorOptimization.java.

Changes:
- Move TopNRowNumberNode.java to
presto-spi/src/main/java/com/facebook/presto/spi/plan/
- Change extends InternalPlanNode to extends PlanNode
- Add visitTopNRowNumber to PlanVisitor.java
- Remove visitTopNRowNumber from InternalPlanVisitor.java
- Add TopNRowNumberNode to CONNECTOR_ACCESSIBLE_PLAN_NODES
- Update all imports across the codebase
- Update protocol YAML files to use .TopNRowNumberNode key
- Regenerate C++ protocol files

Differential Revision: D94627414

## Motivation and Context
As in description

## Impact
As in description

## Test Plan
Existing unit tests


```
== NO RELEASE NOTE ==
```

## Summary by Sourcery

Expose TopNRowNumberNode as a connector-accessible SPI plan node and
align protocol/serialization support.

Enhancements:
- Move TopNRowNumberNode from presto-main-base into presto-spi as a
PlanNode with a PlanVisitor hook so connector optimizers can see and
transform it.
- Tighten TopNRowNumberNode child handling and output variable
construction using standard collections utilities instead of Guava.
- Add a catchableByTry field to ErrorCode in the native protocol to
support JSON round-tripping.

Build:
- Update Java/C++ protocol YAML mappings and generated native protocol
code to use the shortened .TopNRowNumberNode type key instead of the old
fully qualified class name.
feilong-liu added a commit that referenced this pull request Mar 2, 2026
…cess (#27232)

## Description

Similar to changes in #24088

Summary:
Move TopNRowNumberNode from presto-main-base to presto-spi to make it
accessible to connector optimizers in ApplyConnectorOptimization.java.

Changes:
- Move TopNRowNumberNode.java to
presto-spi/src/main/java/com/facebook/presto/spi/plan/
- Change extends InternalPlanNode to extends PlanNode
- Add visitTopNRowNumber to PlanVisitor.java
- Remove visitTopNRowNumber from InternalPlanVisitor.java
- Add TopNRowNumberNode to CONNECTOR_ACCESSIBLE_PLAN_NODES
- Update all imports across the codebase
- Update protocol YAML files to use .TopNRowNumberNode key
- Regenerate C++ protocol files

Differential Revision: D94627414

## Motivation and Context
As in description

## Impact
As in description

## Test Plan
Existing unit tests


```
== NO RELEASE NOTE ==
```

## Summary by Sourcery

Expose TopNRowNumberNode as a connector-accessible SPI plan node and
align protocol/serialization support.

Enhancements:
- Move TopNRowNumberNode from presto-main-base into presto-spi as a
PlanNode with a PlanVisitor hook so connector optimizers can see and
transform it.
- Tighten TopNRowNumberNode child handling and output variable
construction using standard collections utilities instead of Guava.
- Add a catchableByTry field to ErrorCode in the native protocol to
support JSON round-tripping.

Build:
- Update Java/C++ protocol YAML mappings and generated native protocol
code to use the shortened .TopNRowNumberNode type key instead of the old
fully qualified class name.
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.

3 participants