liurenjie1024 commented on code in PR #1441:
URL: https://github.com/apache/iceberg-rust/pull/1441#discussion_r2149562680


##########
crates/iceberg/src/transaction/sort_order.rs:
##########
@@ -15,32 +15,97 @@
 // specific language governing permissions and limitations
 // under the License.
 
+use std::sync::Arc;
+
+use async_trait::async_trait;
+
 use crate::error::Result;
 use crate::spec::{NullOrder, SortDirection, SortField, SortOrder, Transform};
-use crate::transaction::Transaction;
+use crate::table::Table;
+use crate::transaction::{ActionCommit, TransactionAction};
 use crate::{Error, ErrorKind, TableRequirement, TableUpdate};
 
+#[derive(Debug, PartialEq, Eq, Clone)]
+struct PendingSortField {
+    name: String,
+    direction: SortDirection,
+    null_order: NullOrder,
+}
+
 /// Transaction action for replacing sort order.
 pub struct ReplaceSortOrderAction {
-    pub tx: Transaction,
-    pub sort_fields: Vec<SortField>,
+    pending_sort_fields: Vec<PendingSortField>,
 }
 
 impl ReplaceSortOrderAction {
+    pub fn new() -> Self {
+        ReplaceSortOrderAction {
+            pending_sort_fields: vec![],
+        }
+    }
+
     /// Adds a field for sorting in ascending order.
-    pub fn asc(self, name: &str, null_order: NullOrder) -> Result<Self> {
+    pub fn asc(self, name: &str, null_order: NullOrder) -> Self {
         self.add_sort_field(name, SortDirection::Ascending, null_order)
     }
 
     /// Adds a field for sorting in descending order.
-    pub fn desc(self, name: &str, null_order: NullOrder) -> Result<Self> {
+    pub fn desc(self, name: &str, null_order: NullOrder) -> Self {
         self.add_sort_field(name, SortDirection::Descending, null_order)
     }
 
-    /// Finished building the action and apply it to the transaction.
-    pub fn apply(mut self) -> Result<Transaction> {
+    fn add_sort_field(
+        mut self,
+        name: &str,
+        sort_direction: SortDirection,
+        null_order: NullOrder,
+    ) -> Self {
+        self.pending_sort_fields.push(PendingSortField {
+            name: name.to_string(),
+            direction: sort_direction,
+            null_order,
+        });
+
+        self
+    }
+}
+
+impl Default for ReplaceSortOrderAction {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+#[async_trait]
+impl TransactionAction for ReplaceSortOrderAction {
+    async fn commit(self: Arc<Self>, table: &Table) -> Result<ActionCommit> {
+        let pending_sort_fields = self.pending_sort_fields.clone();

Review Comment:
   We don't need to clone whole vec here?



##########
crates/iceberg/src/transaction/sort_order.rs:
##########
@@ -15,32 +15,97 @@
 // specific language governing permissions and limitations
 // under the License.
 
+use std::sync::Arc;
+
+use async_trait::async_trait;
+
 use crate::error::Result;
 use crate::spec::{NullOrder, SortDirection, SortField, SortOrder, Transform};
-use crate::transaction::Transaction;
+use crate::table::Table;
+use crate::transaction::{ActionCommit, TransactionAction};
 use crate::{Error, ErrorKind, TableRequirement, TableUpdate};
 
+#[derive(Debug, PartialEq, Eq, Clone)]
+struct PendingSortField {
+    name: String,
+    direction: SortDirection,
+    null_order: NullOrder,
+}
+
 /// Transaction action for replacing sort order.
 pub struct ReplaceSortOrderAction {
-    pub tx: Transaction,
-    pub sort_fields: Vec<SortField>,
+    pending_sort_fields: Vec<PendingSortField>,
 }
 
 impl ReplaceSortOrderAction {
+    pub fn new() -> Self {
+        ReplaceSortOrderAction {
+            pending_sort_fields: vec![],
+        }
+    }
+
     /// Adds a field for sorting in ascending order.
-    pub fn asc(self, name: &str, null_order: NullOrder) -> Result<Self> {
+    pub fn asc(self, name: &str, null_order: NullOrder) -> Self {
         self.add_sort_field(name, SortDirection::Ascending, null_order)
     }
 
     /// Adds a field for sorting in descending order.
-    pub fn desc(self, name: &str, null_order: NullOrder) -> Result<Self> {
+    pub fn desc(self, name: &str, null_order: NullOrder) -> Self {
         self.add_sort_field(name, SortDirection::Descending, null_order)
     }
 
-    /// Finished building the action and apply it to the transaction.
-    pub fn apply(mut self) -> Result<Transaction> {
+    fn add_sort_field(
+        mut self,
+        name: &str,
+        sort_direction: SortDirection,
+        null_order: NullOrder,
+    ) -> Self {
+        self.pending_sort_fields.push(PendingSortField {
+            name: name.to_string(),
+            direction: sort_direction,
+            null_order,
+        });
+
+        self
+    }
+}
+
+impl Default for ReplaceSortOrderAction {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+#[async_trait]
+impl TransactionAction for ReplaceSortOrderAction {
+    async fn commit(self: Arc<Self>, table: &Table) -> Result<ActionCommit> {
+        let pending_sort_fields = self.pending_sort_fields.clone();
+
+        let sort_fields: Result<Vec<SortField>> = pending_sort_fields
+            .iter()
+            .map(|p| {
+                let field_id = table
+                    .metadata()
+                    .current_schema()
+                    .field_id_by_name(p.name.as_str())
+                    .ok_or_else(|| {
+                        Error::new(
+                            ErrorKind::DataInvalid,
+                            format!("Cannot find field {} in table schema", 
p.name),
+                        )
+                    })?;
+
+                Ok(SortField::builder()
+                    .source_id(field_id)
+                    .transform(Transform::Identity)
+                    .direction(p.direction)
+                    .null_order(p.null_order)
+                    .build())
+            })
+            .collect();
+
         let unbound_sort_order = SortOrder::builder()
-            .with_fields(self.sort_fields)
+            .with_fields(sort_fields?)
             .build_unbound()?;

Review Comment:
   We should use `build_bound` to resue the verification logic in `SortOrder` 
builder.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscr...@iceberg.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscr...@iceberg.apache.org
For additional commands, e-mail: issues-h...@iceberg.apache.org

Reply via email to