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}
@@ -325,7 +340,7 @@ struct TableMetadataBuilder::Impl {
325340 }
326341 }
327342
328- int32_t reuseOrCreateNewSortOrderId (const SortOrder& new_order) {
343+ int32_t ReuseOrCreateNewSortOrderId (const SortOrder& new_order) {
329344 if (new_order.is_unsorted ()) {
330345 return SortOrder::kUnsortedOrderId ;
331346 }
@@ -461,7 +476,7 @@ TableMetadataBuilder& TableMetadataBuilder::SetDefaultSortOrder(int32_t order_id
461476
462477TableMetadataBuilder& TableMetadataBuilder::AddSortOrder (
463478 std::shared_ptr<SortOrder> order) {
464- int32_t new_order_id = impl_->reuseOrCreateNewSortOrderId (*order);
479+ int32_t new_order_id = impl_->ReuseOrCreateNewSortOrderId (*order);
465480
466481 if (impl_->sort_orders_by_id .find (new_order_id) != impl_->sort_orders_by_id .end ()) {
467482 // update last_added_order_id if the order was added in this set of changes (since it
@@ -479,42 +494,20 @@ TableMetadataBuilder& TableMetadataBuilder::AddSortOrder(
479494 return *this ;
480495 }
481496
482- // Get current schema for validation
483- auto schema_result = impl_->metadata .Schema ();
484- if (!schema_result) {
485- impl_->errors .emplace_back (
486- ErrorKind::kInvalidArgument ,
487- std::format (" Cannot find current schema: {}" , schema_result.error ().message ));
488- return *this ;
489- }
490-
491- auto schema = schema_result.value ();
492-
493- // Validate the sort order against the schema
494- auto validate_status = order->Validate (*schema);
495- if (!validate_status) {
496- impl_->errors .emplace_back (
497- ErrorKind::kInvalidArgument ,
498- std::format (" Sort order validation failed: {}" , validate_status.error ().message ));
499- return *this ;
500- }
497+ // Get current schema and validate the sort order against it
498+ BUILDER_ASSIGN_OR_RETURN (auto schema, impl_->metadata .Schema ());
499+ BUILDER_RETURN_IF_ERROR (order->Validate (*schema));
501500
502501 std::shared_ptr<SortOrder> new_order;
503502 if (order->is_unsorted ()) {
504503 new_order = SortOrder::Unsorted ();
505504 } else {
506- // TODO(Li Feiyang): rebuild the sort order using new column ids (freshSortOrder)
507- // For now, create a new sort order with the provided fields
508- auto sort_order_result = SortOrder::Make (
509- *schema, new_order_id,
510- std::vector<SortField>(order->fields ().begin (), order->fields ().end ()));
511- if (!sort_order_result) {
512- impl_->errors .emplace_back (ErrorKind::kInvalidArgument ,
513- std::format (" Failed to create sort order: {}" ,
514- sort_order_result.error ().message ));
515- return *this ;
516- }
517- new_order = std::move (sort_order_result.value ());
505+ // Unlike freshSortOrder from Java impl, we don't use field name from old bound
506+ // schema to rebuild the sort order.
507+ BUILDER_ASSIGN_OR_RETURN (
508+ new_order,
509+ SortOrder::Make (new_order_id, std::vector<SortField>(order->fields ().begin (),
510+ order->fields ().end ())));
518511 }
519512
520513 impl_->metadata .sort_orders .push_back (new_order);
0 commit comments