2323#include < chrono>
2424#include < cstdint>
2525#include < format>
26- #include < ranges>
2726#include < optional>
27+ #include < ranges>
2828#include < string>
2929#include < unordered_map>
3030
4545
4646namespace iceberg {
4747
48+ #define BUILDER_RETURN_IF_ERROR (result ) \
49+ if (auto && result_name = result; !result_name) [[unlikely]] { \
50+ impl_->errors .emplace_back (std::move (result_name.error ())); \
51+ return *this ; \
52+ }
53+
54+ #define BUILDER_ASSIGN_OR_RETURN_IMPL (result_name, lhs, rexpr ) \
55+ auto && result_name = (rexpr); \
56+ BUILDER_RETURN_IF_ERROR (result_name) \
57+ lhs = std::move(result_name.value());
58+
59+ #define BUILDER_ASSIGN_OR_RETURN (lhs, rexpr ) \
60+ BUILDER_ASSIGN_OR_RETURN_IMPL (ICEBERG_ASSIGN_OR_RAISE_NAME(result_, __COUNTER__), lhs, \
61+ rexpr)
62+
4863namespace {
4964const TimePointMs kInvalidLastUpdatedMs = TimePointMs::min ();
5065}
@@ -322,7 +337,7 @@ struct TableMetadataBuilder::Impl {
322337 }
323338 }
324339
325- int32_t reuseOrCreateNewSortOrderId (const SortOrder& new_order) {
340+ int32_t ReuseOrCreateNewSortOrderId (const SortOrder& new_order) {
326341 if (new_order.is_unsorted ()) {
327342 return SortOrder::kUnsortedOrderId ;
328343 }
@@ -457,7 +472,7 @@ TableMetadataBuilder& TableMetadataBuilder::SetDefaultSortOrder(int32_t order_id
457472
458473TableMetadataBuilder& TableMetadataBuilder::AddSortOrder (
459474 std::shared_ptr<SortOrder> order) {
460- int32_t new_order_id = impl_->reuseOrCreateNewSortOrderId (*order);
475+ int32_t new_order_id = impl_->ReuseOrCreateNewSortOrderId (*order);
461476
462477 if (impl_->sort_orders_by_id .find (new_order_id) != impl_->sort_orders_by_id .end ()) {
463478 // update last_added_order_id if the order was added in this set of changes (since it
@@ -475,42 +490,20 @@ TableMetadataBuilder& TableMetadataBuilder::AddSortOrder(
475490 return *this ;
476491 }
477492
478- // Get current schema for validation
479- auto schema_result = impl_->metadata .Schema ();
480- if (!schema_result) {
481- impl_->errors .emplace_back (
482- ErrorKind::kInvalidArgument ,
483- std::format (" Cannot find current schema: {}" , schema_result.error ().message ));
484- return *this ;
485- }
486-
487- auto schema = schema_result.value ();
488-
489- // Validate the sort order against the schema
490- auto validate_status = order->Validate (*schema);
491- if (!validate_status) {
492- impl_->errors .emplace_back (
493- ErrorKind::kInvalidArgument ,
494- std::format (" Sort order validation failed: {}" , validate_status.error ().message ));
495- return *this ;
496- }
493+ // Get current schema and validate the sort order against it
494+ BUILDER_ASSIGN_OR_RETURN (auto schema, impl_->metadata .Schema ());
495+ BUILDER_RETURN_IF_ERROR (order->Validate (*schema));
497496
498497 std::shared_ptr<SortOrder> new_order;
499498 if (order->is_unsorted ()) {
500499 new_order = SortOrder::Unsorted ();
501500 } else {
502- // TODO(Li Feiyang): rebuild the sort order using new column ids (freshSortOrder)
503- // For now, create a new sort order with the provided fields
504- auto sort_order_result = SortOrder::Make (
505- *schema, new_order_id,
506- std::vector<SortField>(order->fields ().begin (), order->fields ().end ()));
507- if (!sort_order_result) {
508- impl_->errors .emplace_back (ErrorKind::kInvalidArgument ,
509- std::format (" Failed to create sort order: {}" ,
510- sort_order_result.error ().message ));
511- return *this ;
512- }
513- new_order = std::move (sort_order_result.value ());
501+ // Unlike freshSortOrder from Java impl, we don't use field name from old bound
502+ // schema to rebuild the sort order.
503+ BUILDER_ASSIGN_OR_RETURN (
504+ new_order,
505+ SortOrder::Make (new_order_id, std::vector<SortField>(order->fields ().begin (),
506+ order->fields ().end ())));
514507 }
515508
516509 impl_->metadata .sort_orders .push_back (new_order);
0 commit comments