Skip to content

feat(native): Support sorted by during write to Iceberg tables#26182

Open
PingLiuPing wants to merge 6 commits intoprestodb:masterfrom
PingLiuPing:lp_iceberg_insertion_sort_order_no_test
Open

feat(native): Support sorted by during write to Iceberg tables#26182
PingLiuPing wants to merge 6 commits intoprestodb:masterfrom
PingLiuPing:lp_iceberg_insertion_sort_order_no_test

Conversation

@PingLiuPing
Copy link
Contributor

Description

Support sorted by when writing to iceberg table.

Reviewers, please review the last commit only for this PR.

Motivation and Context

Impact

Test Plan

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.

Release Notes

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

== RELEASE NOTES ==

Iceberg Connector Changes
* Add support for sorted by when writing to Iceberg tables.

@PingLiuPing PingLiuPing self-assigned this Sep 29, 2025
@prestodb-ci prestodb-ci added the from:IBM PR from IBM label Sep 29, 2025
@prestodb-ci prestodb-ci requested review from a team and infvg and removed request for a team September 29, 2025 15:55
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Sep 29, 2025

Reviewer's Guide

This PR introduces support for sorted-by ordering when writing to Iceberg tables by enabling a native insertion path behind a compile-time flag, parsing and propagating sort fields through the Velox connector, and updating the Java metadata and sink implementations to be session-aware and robust for partition transforms and JSON decimal handling.

ER diagram for PartitionTransformType enum changes

erDiagram
    PartitionTransformType {
        IDENTITY
        HOUR
        DAY
        MONTH
        YEAR
        BUCKET
        TRUNCATE
    }
Loading

Class diagram for updated IcebergPrestoToVeloxConnector and related types

classDiagram
    class IcebergPrestoToVeloxConnector {
        +toVeloxInsertTableHandle(createHandle, typeParser, pool)
        +toVeloxInsertTableHandle(insertHandle, typeParser, pool)
        +toIcebergColumns(inputColumns, typeParser, hasPartitionColumn)
        +toIcebergSortingColumns(sortFields, schema)
        +toVeloxIcebergPartitionField(field, typeParser, schema)
        +toVeloxIcebergPartitionSpec(spec, typeParser)
    }
    class HivePrestoToVeloxConnector {
        +toVeloxInsertTableHandle(createHandle, typeParser, pool)
        +toVeloxInsertTableHandle(insertHandle, typeParser, pool)
    }
    class PrestoToVeloxConnector {
        +toVeloxInsertTableHandle(createHandle, typeParser, pool)
        +toVeloxInsertTableHandle(insertHandle, typeParser, pool)
    }
    IcebergPrestoToVeloxConnector --|> PrestoToVeloxConnector
    HivePrestoToVeloxConnector --|> PrestoToVeloxConnector
    IcebergPrestoToVeloxConnector o-- "IcebergColumnHandle"
    IcebergPrestoToVeloxConnector o-- "IcebergSortingColumn"
    IcebergPrestoToVeloxConnector o-- "IcebergPartitionSpec"
    IcebergPrestoToVeloxConnector o-- "TypeParser"
    IcebergPrestoToVeloxConnector o-- "MemoryPool"
    HivePrestoToVeloxConnector o-- "TypeParser"
    HivePrestoToVeloxConnector o-- "MemoryPool"
    PrestoToVeloxConnector o-- "TypeParser"
    PrestoToVeloxConnector o-- "MemoryPool"
Loading

Class diagram for updated IcebergColumnHandle Java class

classDiagram
    class IcebergColumnHandle {
        +create(column, typeManager, columnType)
        +create(partitionFieldId, column, typeManager, columnType)
        +getPushedDownSubfield(column)
        -columnIdentity
        -type
        -doc
        -columnType
    }
Loading

File-Level Changes

Change Details Files
Enable Iceberg native insertion via PRESTO_ENABLE_ICEBERG_NATIVE_INSERTION
  • Define the compile flag in CMakeLists.txt and Makefile
  • Guard connector methods and protocol types behind the flag
  • Add overloads of toVeloxInsertTableHandle with MemoryPool parameter
  • Implement toIcebergColumns, toIcebergSortingColumns, toVeloxIcebergPartitionSpec helpers
presto-native-execution/CMakeLists.txt
presto-native-execution/Makefile
presto-native-execution/presto_cpp/main/connectors/PrestoToVeloxConnector.cpp
presto-native-execution/presto_cpp/main/connectors/PrestoToVeloxConnector.h
presto-native-execution/presto_cpp/presto_protocol/connector/iceberg/presto_protocol_iceberg.h
presto-native-execution/presto_cpp/presto_protocol/connector/iceberg/presto_protocol_iceberg.cpp
presto-native-execution/presto_cpp/presto_protocol/connector/iceberg/presto_protocol_iceberg.yml
Propagate sorted-by order through the Velox connector
  • Parse SortField.sortOrder into velox::core::SortOrder
  • Include sortedBy vector in IcebergInsertTableHandle construction
  • Update query plan converter to pass MemoryPool to connector
  • Expose sorting parameters in IcebergPageSink
presto-native-execution/presto_cpp/main/connectors/PrestoToVeloxConnector.cpp
presto-native-execution/presto_cpp/main/types/PrestoToVeloxQueryPlan.cpp
presto-native-execution/presto_cpp/main/connectors/PrestoToVeloxConnector.h
presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergPageSink.java
Make Java Iceberg metadata and utilities session-aware
  • Add ConnectorSession parameter to getColumns and requiredColumnsForDeletes
  • Switch partition transform type to ALL for INSERT queries
  • Update callers in IcebergUtil, PageSourceProvider, metadata classes, ChangelogSplitSource
  • Adjust POM dependency scopes to support session changes
presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergUtil.java
presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergPageSourceProvider.java
presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergAbstractMetadata.java
presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergHiveMetadata.java
presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergNativeMetadata.java
presto-iceberg/src/main/java/com/facebook/presto/iceberg/changelog/ChangelogSplitSource.java
presto-iceberg/pom.xml
Refine partition JSON decimal and transform type handling
  • Enhance PartitionData.getValue to support long, int, BigInteger for DECIMAL
  • Reorder PartitionTransformType enum entries and mapping tables
presto-iceberg/src/main/java/com/facebook/presto/iceberg/PartitionData.java
presto-iceberg/src/main/java/com/facebook/presto/iceberg/PartitionTransformType.java
presto-native-execution/presto_cpp/presto_protocol/connector/iceberg/presto_protocol_iceberg.h
presto-native-execution/presto_cpp/presto_protocol/connector/iceberg/presto_protocol_iceberg.cpp

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
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 there - I've reviewed your changes and they look great!


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.

const protocol::CreateHandle* createHandle,
const TypeParser& typeParser) const {
const TypeParser& typeParser,
memory::MemoryPool* pool) const {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is memory pool variable added ? Doesn't seem like its used. Memory pool should be used for allocating from operators not during this conversion.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the comment.
MemoryPool is needed by Iceberg connector. When doing partition transform, we need to create new vectors to hold the transformed value.
And it is not needed here in Hive connector, but since both of Hive and Iceberg inherit from base class and overwrite this method toVeloxInsertTableHandle, I add this parameter in base class.

if (partitionValue.isLong()) {
return BigDecimal.valueOf(partitionValue.asLong(), ((DecimalType) type).scale());
}
else if (partitionValue.isInt()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add some test for this logic ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, I think I have test case cover this, let me find it.

Copy link
Contributor Author

@PingLiuPing PingLiuPing Oct 2, 2025

Choose a reason for hiding this comment

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

Yes, I have testcase cover this,
Screenshot 2025-10-02 at 12 04 13

And it can be easily tested in presto-cli. The logic here is, in Velox decimal is represented as integer (int64/int128). But when we passing the partition value back to Presto, it is encoded in json format, and here when decode the value, if the value is a small integer it will be treated as int32.

presto:iceberg> insert into identity_t2 values(1, -123, cast('89.124' AS decimal(5,3)), 'ABCD QWERT', x'455843454C4C454E54');
INSERT: 1 row

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the comment.
This is a mistake, and the change is duplicate. It must be caused by multiple rebase and merging when I maintain these branches locally. I've reverted all the changes in this file.

@PingLiuPing PingLiuPing force-pushed the lp_iceberg_insertion_sort_order_no_test branch 2 times, most recently from 47e676e to 7bea642 Compare October 2, 2025 11:08
@PingLiuPing PingLiuPing changed the title [native] Support sorted by during write to Iceberg tables feat(native): Support sorted by during write to Iceberg tables Oct 3, 2025
@PingLiuPing
Copy link
Contributor Author

For release-notes pipeline error, opened an issue #26222

yingsu00
yingsu00 previously approved these changes Oct 3, 2025
Copy link
Contributor

@yingsu00 yingsu00 left a comment

Choose a reason for hiding this comment

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

Approve contingent to the mvn failure resolved.

@unidevel
Copy link
Contributor

unidevel commented Oct 3, 2025

You may rebase fix the CI now.

@PingLiuPing PingLiuPing force-pushed the lp_iceberg_insertion_sort_order_no_test branch from 7bea642 to f8dfb27 Compare October 3, 2025 10:53
std::vector<connector::hive::iceberg::IcebergSortingColumn> sortedBy;
sortedBy.reserve(sortFields.size());
for (const auto& sortField : sortFields) {
velox::core::SortOrder veloxSortOrder(
Copy link
Contributor

Choose a reason for hiding this comment

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

Please can you leave a comment stating this matches asc/desc, nulls first/nulls last.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the comment. Let me add a comment.


private:
std::vector<std::shared_ptr<const velox::connector::hive::HiveColumnHandle>>
std::vector<std::shared_ptr<const velox::connector::hive::iceberg::IcebergColumnHandle>>
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this a bug ? Did you intentionally leave HiveColumnHandle in previous commit ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the comment.
Yes, the commit here matches the code in velox. And in velox IcebergColumnHandle is added later. So I change this to match the code in velox.
When I test the code I follow:
Presto PR1 -> Velox PR 1
Presto PR2 -> Velox PR 2

@PingLiuPing PingLiuPing force-pushed the lp_iceberg_insertion_sort_order_no_test branch from f8dfb27 to ba1006b Compare October 10, 2025 09:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

from:IBM PR from IBM

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants