You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iceberg.apache.org by gi...@apache.org on 2024/09/08 16:20:54 UTC

(iceberg-rust) branch gh-pages updated: deploy: 58123990c304b72139651a16f45f6505bc868cc3

This is an automated email from the ASF dual-hosted git repository.

github-bot pushed a commit to branch gh-pages
in repository https://gitbox.apache.org/repos/asf/iceberg-rust.git


The following commit(s) were added to refs/heads/gh-pages by this push:
     new 928bfd3d deploy: 58123990c304b72139651a16f45f6505bc868cc3
928bfd3d is described below

commit 928bfd3def93e125f6ac82352e321005759ce3a0
Author: Xuanwo <Xu...@users.noreply.github.com>
AuthorDate: Sun Sep 8 16:20:49 2024 +0000

    deploy: 58123990c304b72139651a16f45f6505bc868cc3
---
 api/iceberg/spec/struct.PartitionField.html        |   2 +-
 api/iceberg/spec/struct.PartitionSpec.html         |  23 +-
 api/iceberg/spec/struct.PartitionSpecBuilder.html  |  20 +-
 api/iceberg/spec/struct.UnboundPartitionField.html |  12 +-
 api/iceberg/spec/struct.UnboundPartitionSpec.html  |  19 +-
 .../spec/struct.UnboundPartitionSpecBuilder.html   |  14 +-
 api/iceberg/spec/type.UnboundPartitionSpecRef.html |   2 +-
 api/search-index.js                                |   2 +-
 api/search.desc/iceberg/iceberg-desc-0-.js         |   2 +-
 api/src/iceberg/spec/partition.rs.html             | 826 ++++++++++++++++++++-
 10 files changed, 881 insertions(+), 41 deletions(-)

diff --git a/api/iceberg/spec/struct.PartitionField.html b/api/iceberg/spec/struct.PartitionField.html
index 4ca88d1f..31d872f0 100644
--- a/api/iceberg/spec/struct.PartitionField.html
+++ b/api/iceberg/spec/struct.PartitionField.html
@@ -14,7 +14,7 @@ On the builder, call <code>.source_id(...)</code>, <code>.field_id(...)</code>,
 Finally, call <code>.build()</code> to create the instance of <code>PartitionField</code>.</p>
 </div></details></div></details><details class="toggle implementors-toggle" open><summary><section id="impl-PartitionField-1" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#50-55">source</a><a href="#impl-PartitionField-1" class="anchor">§</a><h3 class="code-header">impl <a class="struct" href="struct.PartitionField.html" title="struct iceberg::spec::PartitionField">PartitionField</a></h3></section></summary><div class="impl-items"><details class="to [...]
 </div></details></div></details></div><h2 id="trait-implementations" class="section-header">Trait Implementations<a href="#trait-implementations" class="anchor">§</a></h2><div id="trait-implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-Clone-for-PartitionField" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#36">source</a><a href="#impl-Clone-for-PartitionField" class="anchor">§</a><h3 class="code-header [...]
-    __D: <a class="trait" href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserializer.html" title="trait serde::de::Deserializer">Deserializer</a>&lt;'de&gt;,</div></h4></section></summary><div class='docblock'>Deserialize this value from the given Serde deserializer. <a href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserialize.html#tymethod.deserialize">Read more</a></div></details></div></details><details class="toggle implementors-toggle" open><summary><section id="impl-From% [...]
+    __D: <a class="trait" href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserializer.html" title="trait serde::de::Deserializer">Deserializer</a>&lt;'de&gt;,</div></h4></section></summary><div class='docblock'>Deserialize this value from the given Serde deserializer. <a href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserialize.html#tymethod.deserialize">Read more</a></div></details></div></details><details class="toggle implementors-toggle" open><summary><section id="impl-From% [...]
 by <code>==</code>.</div></details><details class="toggle method-toggle" open><summary><section id="method.ne" class="method trait-impl"><span class="rightside"><span class="since" title="Stable since Rust version 1.0.0">1.0.0</span> · <a class="src" href="https://doc.rust-lang.org/nightly/src/core/cmp.rs.html#263">source</a></span><a href="#method.ne" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/nightly/core/cmp/trait.PartialEq.html#method.ne" class= [...]
 sufficient, and should not be overridden without very good reason.</div></details></div></details><details class="toggle implementors-toggle" open><summary><section id="impl-Serialize-for-PartitionField" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#36">source</a><a href="#impl-Serialize-for-PartitionField" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serialize.html" title="tra [...]
     __S: <a class="trait" href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serializer.html" title="trait serde::ser::Serializer">Serializer</a>,</div></h4></section></summary><div class='docblock'>Serialize this value into the given Serde serializer. <a href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serialize.html#tymethod.serialize">Read more</a></div></details></div></details><section id="impl-Eq-for-PartitionField" class="impl"><a class="src rightside" href="../../src/iceberg/ [...]
diff --git a/api/iceberg/spec/struct.PartitionSpec.html b/api/iceberg/spec/struct.PartitionSpec.html
index 8c0dde19..9dc7dcaf 100644
--- a/api/iceberg/spec/struct.PartitionSpec.html
+++ b/api/iceberg/spec/struct.PartitionSpec.html
@@ -1,14 +1,29 @@
-<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Partition spec that defines how to produce a tuple of partition values from a record."><title>PartitionSpec in iceberg::spec - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,FiraSans- [...]
-</div></details><h2 id="implementations" class="section-header">Implementations<a href="#implementations" class="anchor">§</a></h2><div id="implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-PartitionSpec" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#67-124">source</a><a href="#impl-PartitionSpec" class="anchor">§</a><h3 class="code-header">impl <a class="struct" href="struct.PartitionSpec.html" title= [...]
+<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Partition spec that defines how to produce a tuple of partition values from a record."><title>PartitionSpec in iceberg::spec - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,FiraSans- [...]
+</div></details><h2 id="implementations" class="section-header">Implementations<a href="#implementations" class="anchor">§</a></h2><div id="implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-PartitionSpec" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#67-178">source</a><a href="#impl-PartitionSpec" class="anchor">§</a><h3 class="code-header">impl <a class="struct" href="struct.PartitionSpec.html" title= [...]
 </div></details><details class="toggle method-toggle" open><summary><section id="method.spec_id" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#74-76">source</a><h4 class="code-header">pub fn <a href="#method.spec_id" class="fn">spec_id</a>(&amp;self) -&gt; <a class="primitive" href="https://doc.rust-lang.org/nightly/std/primitive.i32.html">i32</a></h4></section></summary><div class="docblock"><p>Spec id of the partition spec</p>
 </div></details><details class="toggle method-toggle" open><summary><section id="method.fields" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#79-81">source</a><h4 class="code-header">pub fn <a href="#method.fields" class="fn">fields</a>(&amp;self) -&gt; &amp;[<a class="struct" href="struct.PartitionField.html" title="struct iceberg::spec::PartitionField">PartitionField</a>]</h4></section></summary><div class="docblock"><p>Fields of the partition spec</p>
 </div></details><details class="toggle method-toggle" open><summary><section id="method.is_unpartitioned" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#86-92">source</a><h4 class="code-header">pub fn <a href="#method.is_unpartitioned" class="fn">is_unpartitioned</a>(&amp;self) -&gt; <a class="primitive" href="https://doc.rust-lang.org/nightly/std/primitive.bool.html">bool</a></h4></section></summary><div class="docblock"><p>Returns if the partitio [...]
 <p>A <a href="struct.PartitionSpec.html" title="struct iceberg::spec::PartitionSpec"><code>PartitionSpec</code></a> is unpartitioned if it has no fields or all fields are <a href="enum.Transform.html#variant.Void" title="variant iceberg::spec::Transform::Void"><code>Transform::Void</code></a> transform.</p>
 </div></details><details class="toggle method-toggle" open><summary><section id="method.partition_type" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#95-116">source</a><h4 class="code-header">pub fn <a href="#method.partition_type" class="fn">partition_type</a>(&amp;self, schema: &amp;<a class="struct" href="struct.Schema.html" title="struct iceberg::spec::Schema">Schema</a>) -&gt; <a class="type" href="../type.Result.html" title="type iceberg::Re [...]
-</div></details><details class="toggle method-toggle" open><summary><section id="method.to_unbound" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#121-123">source</a><h4 class="code-header">pub fn <a href="#method.to_unbound" class="fn">to_unbound</a>(self) -&gt; <a class="struct" href="struct.UnboundPartitionSpec.html" title="struct iceberg::spec::UnboundPartitionSpec">UnboundPartitionSpec</a></h4></section></summary><div class="docblock"><p>Turn  [...]
+</div></details><details class="toggle method-toggle" open><summary><section id="method.into_unbound" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#121-123">source</a><h4 class="code-header">pub fn <a href="#method.into_unbound" class="fn">into_unbound</a>(self) -&gt; <a class="struct" href="struct.UnboundPartitionSpec.html" title="struct iceberg::spec::UnboundPartitionSpec">UnboundPartitionSpec</a></h4></section></summary><div class="docblock"><p [...]
 <p>The <code>field_id</code> is retained as <code>partition_id</code> in the unbound partition spec.</p>
+</div></details><details class="toggle method-toggle" open><summary><section id="method.is_compatible_with" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#134-149">source</a><h4 class="code-header">pub fn <a href="#method.is_compatible_with" class="fn">is_compatible_with</a>(&amp;self, other: &amp;<a class="struct" href="struct.UnboundPartitionSpec.html" title="struct iceberg::spec::UnboundPartitionSpec">UnboundPartitionSpec</a>) -&gt; <a class="pr [...]
+<p>Returns true if the partition spec is equal to the other spec with partition field ids ignored and
+spec_id ignored. The following must be identical:</p>
+<ul>
+<li>The number of fields</li>
+<li>Field order</li>
+<li>Field names</li>
+<li>Source column ids</li>
+<li>Transforms</li>
+</ul>
+</div></details><details class="toggle method-toggle" open><summary><section id="method.has_sequential_ids" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#154-167">source</a><h4 class="code-header">pub fn <a href="#method.has_sequential_ids" class="fn">has_sequential_ids</a>(&amp;self) -&gt; <a class="primitive" href="https://doc.rust-lang.org/nightly/std/primitive.bool.html">bool</a></h4></section></summary><div class="docblock"><p>Check if this p [...]
+Sequential ids start from 1000 and increment by 1 for each field.
+This is required for spec version 1</p>
+</div></details><details class="toggle method-toggle" open><summary><section id="method.highest_field_id" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#171-177">source</a><h4 class="code-header">pub fn <a href="#method.highest_field_id" class="fn">highest_field_id</a>(&amp;self) -&gt; <a class="primitive" href="https://doc.rust-lang.org/nightly/std/primitive.i32.html">i32</a></h4></section></summary><div class="docblock"><p>Get the highest field i [...]
+If the partition spec is unpartitioned, it returns the last unpartitioned last assigned id (999).</p>
 </div></details></div></details></div><h2 id="trait-implementations" class="section-header">Trait Implementations<a href="#trait-implementations" class="anchor">§</a></h2><div id="trait-implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-Clone-for-PartitionSpec" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#58">source</a><a href="#impl-Clone-for-PartitionSpec" class="anchor">§</a><h3 class="code-header"> [...]
-    __D: <a class="trait" href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserializer.html" title="trait serde::de::Deserializer">Deserializer</a>&lt;'de&gt;,</div></h4></section></summary><div class='docblock'>Deserialize this value from the given Serde deserializer. <a href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserialize.html#tymethod.deserialize">Read more</a></div></details></div></details><details class="toggle implementors-toggle" open><summary><section id="impl-From% [...]
+    __D: <a class="trait" href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserializer.html" title="trait serde::de::Deserializer">Deserializer</a>&lt;'de&gt;,</div></h4></section></summary><div class='docblock'>Deserialize this value from the given Serde deserializer. <a href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserialize.html#tymethod.deserialize">Read more</a></div></details></div></details><details class="toggle implementors-toggle" open><summary><section id="impl-From% [...]
 by <code>==</code>.</div></details><details class="toggle method-toggle" open><summary><section id="method.ne" class="method trait-impl"><span class="rightside"><span class="since" title="Stable since Rust version 1.0.0">1.0.0</span> · <a class="src" href="https://doc.rust-lang.org/nightly/src/core/cmp.rs.html#263">source</a></span><a href="#method.ne" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/nightly/core/cmp/trait.PartialEq.html#method.ne" class= [...]
 sufficient, and should not be overridden without very good reason.</div></details></div></details><details class="toggle implementors-toggle" open><summary><section id="impl-Serialize-for-PartitionSpec" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#58">source</a><a href="#impl-Serialize-for-PartitionSpec" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serialize.html" title="trait [...]
     __S: <a class="trait" href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serializer.html" title="trait serde::ser::Serializer">Serializer</a>,</div></h4></section></summary><div class='docblock'>Serialize this value into the given Serde serializer. <a href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serialize.html#tymethod.serialize">Read more</a></div></details></div></details><section id="impl-Eq-for-PartitionSpec" class="impl"><a class="src rightside" href="../../src/iceberg/s [...]
diff --git a/api/iceberg/spec/struct.PartitionSpecBuilder.html b/api/iceberg/spec/struct.PartitionSpecBuilder.html
index 8b823a28..0f40fe6a 100644
--- a/api/iceberg/spec/struct.PartitionSpecBuilder.html
+++ b/api/iceberg/spec/struct.PartitionSpecBuilder.html
@@ -1,29 +1,29 @@
-<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Create valid partition specs for a given schema."><title>PartitionSpecBuilder in iceberg::spec - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,FiraSans-Regular-018c141bf0843ffd.woff2 [...]
-</div></details><h2 id="implementations" class="section-header">Implementations<a href="#implementations" class="anchor">§</a></h2><div id="implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-PartitionSpecBuilder%3C'a%3E" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#274-504">source</a><a href="#impl-PartitionSpecBuilder%3C'a%3E" class="anchor">§</a><h3 class="code-header">impl&lt;'a&gt; <a class="struct [...]
-</div></details><details class="toggle method-toggle" open><summary><section id="method.new_from_unbound" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#286-294">source</a><h4 class="code-header">pub fn <a href="#method.new_from_unbound" class="fn">new_from_unbound</a>(
+<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Create valid partition specs for a given schema."><title>PartitionSpecBuilder in iceberg::spec - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,FiraSans-Regular-018c141bf0843ffd.woff2 [...]
+</div></details><h2 id="implementations" class="section-header">Implementations<a href="#implementations" class="anchor">§</a></h2><div id="implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-PartitionSpecBuilder%3C'a%3E" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#336-566">source</a><a href="#impl-PartitionSpecBuilder%3C'a%3E" class="anchor">§</a><h3 class="code-header">impl&lt;'a&gt; <a class="struct [...]
+</div></details><details class="toggle method-toggle" open><summary><section id="method.new_from_unbound" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#348-356">source</a><h4 class="code-header">pub fn <a href="#method.new_from_unbound" class="fn">new_from_unbound</a>(
     unbound: <a class="struct" href="struct.UnboundPartitionSpec.html" title="struct iceberg::spec::UnboundPartitionSpec">UnboundPartitionSpec</a>,
     schema: &amp;'a <a class="struct" href="struct.Schema.html" title="struct iceberg::spec::Schema">Schema</a>,
 ) -&gt; <a class="type" href="../type.Result.html" title="type iceberg::Result">Result</a>&lt;Self&gt;</h4></section></summary><div class="docblock"><p>Create a new partition spec builder from an existing unbound partition spec.</p>
-</div></details><details class="toggle method-toggle" open><summary><section id="method.with_last_assigned_field_id" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#301-304">source</a><h4 class="code-header">pub fn <a href="#method.with_last_assigned_field_id" class="fn">with_last_assigned_field_id</a>(self, last_assigned_field_id: <a class="primitive" href="https://doc.rust-lang.org/nightly/std/primitive.i32.html">i32</a>) -&gt; Self</h4></section> [...]
+</div></details><details class="toggle method-toggle" open><summary><section id="method.with_last_assigned_field_id" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#363-366">source</a><h4 class="code-header">pub fn <a href="#method.with_last_assigned_field_id" class="fn">with_last_assigned_field_id</a>(self, last_assigned_field_id: <a class="primitive" href="https://doc.rust-lang.org/nightly/std/primitive.i32.html">i32</a>) -&gt; Self</h4></section> [...]
 <p>Set this field when a new partition spec is created for an existing TableMetaData.
 As <code>field_id</code> must be unique in V2 metadata, this should be set to
 the highest field id used previously.</p>
-</div></details><details class="toggle method-toggle" open><summary><section id="method.with_spec_id" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#307-310">source</a><h4 class="code-header">pub fn <a href="#method.with_spec_id" class="fn">with_spec_id</a>(self, spec_id: <a class="primitive" href="https://doc.rust-lang.org/nightly/std/primitive.i32.html">i32</a>) -&gt; Self</h4></section></summary><div class="docblock"><p>Set the spec id for the p [...]
-</div></details><details class="toggle method-toggle" open><summary><section id="method.add_partition_field" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#313-340">source</a><h4 class="code-header">pub fn <a href="#method.add_partition_field" class="fn">add_partition_field</a>(
+</div></details><details class="toggle method-toggle" open><summary><section id="method.with_spec_id" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#369-372">source</a><h4 class="code-header">pub fn <a href="#method.with_spec_id" class="fn">with_spec_id</a>(self, spec_id: <a class="primitive" href="https://doc.rust-lang.org/nightly/std/primitive.i32.html">i32</a>) -&gt; Self</h4></section></summary><div class="docblock"><p>Set the spec id for the p [...]
+</div></details><details class="toggle method-toggle" open><summary><section id="method.add_partition_field" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#375-402">source</a><h4 class="code-header">pub fn <a href="#method.add_partition_field" class="fn">add_partition_field</a>(
     self,
     source_name: impl <a class="trait" href="https://doc.rust-lang.org/nightly/core/convert/trait.AsRef.html" title="trait core::convert::AsRef">AsRef</a>&lt;<a class="primitive" href="https://doc.rust-lang.org/nightly/std/primitive.str.html">str</a>&gt;,
     target_name: impl <a class="trait" href="https://doc.rust-lang.org/nightly/core/convert/trait.Into.html" title="trait core::convert::Into">Into</a>&lt;<a class="struct" href="https://doc.rust-lang.org/nightly/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,
     transform: <a class="enum" href="enum.Transform.html" title="enum iceberg::spec::Transform">Transform</a>,
 ) -&gt; <a class="type" href="../type.Result.html" title="type iceberg::Result">Result</a>&lt;Self&gt;</h4></section></summary><div class="docblock"><p>Add a new partition field to the partition spec.</p>
-</div></details><details class="toggle method-toggle" open><summary><section id="method.add_unbound_field" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#346-358">source</a><h4 class="code-header">pub fn <a href="#method.add_unbound_field" class="fn">add_unbound_field</a>(self, field: <a class="struct" href="struct.UnboundPartitionField.html" title="struct iceberg::spec::UnboundPartitionField">UnboundPartitionField</a>) -&gt; <a class="type" href=" [...]
+</div></details><details class="toggle method-toggle" open><summary><section id="method.add_unbound_field" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#408-420">source</a><h4 class="code-header">pub fn <a href="#method.add_unbound_field" class="fn">add_unbound_field</a>(self, field: <a class="struct" href="struct.UnboundPartitionField.html" title="struct iceberg::spec::UnboundPartitionField">UnboundPartitionField</a>) -&gt; <a class="type" href=" [...]
 <p>If partition field id is set, it is used as the field id.
 Otherwise, a new <code>field_id</code> is assigned.</p>
-</div></details><details class="toggle method-toggle" open><summary><section id="method.add_unbound_fields" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#361-370">source</a><h4 class="code-header">pub fn <a href="#method.add_unbound_fields" class="fn">add_unbound_fields</a>(
+</div></details><details class="toggle method-toggle" open><summary><section id="method.add_unbound_fields" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#423-432">source</a><h4 class="code-header">pub fn <a href="#method.add_unbound_fields" class="fn">add_unbound_fields</a>(
     self,
     fields: impl <a class="trait" href="https://doc.rust-lang.org/nightly/core/iter/traits/collect/trait.IntoIterator.html" title="trait core::iter::traits::collect::IntoIterator">IntoIterator</a>&lt;Item = <a class="struct" href="struct.UnboundPartitionField.html" title="struct iceberg::spec::UnboundPartitionField">UnboundPartitionField</a>&gt;,
 ) -&gt; <a class="type" href="../type.Result.html" title="type iceberg::Result">Result</a>&lt;Self&gt;</h4></section></summary><div class="docblock"><p>Wrapper around <code>with_unbound_fields</code> to add multiple partition fields.</p>
-</div></details><details class="toggle method-toggle" open><summary><section id="method.build" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#373-379">source</a><h4 class="code-header">pub fn <a href="#method.build" class="fn">build</a>(self) -&gt; <a class="type" href="../type.Result.html" title="type iceberg::Result">Result</a>&lt;<a class="struct" href="struct.PartitionSpec.html" title="struct iceberg::spec::PartitionSpec">PartitionSpec</a>&gt;< [...]
-</div></details></div></details></div><h2 id="trait-implementations" class="section-header">Trait Implementations<a href="#trait-implementations" class="anchor">§</a></h2><div id="trait-implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-Debug-for-PartitionSpecBuilder%3C'a%3E" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#266">source</a><a href="#impl-Debug-for-PartitionSpecBuilder%3C'a%3E" class="anchor [...]
+</div></details><details class="toggle method-toggle" open><summary><section id="method.build" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#435-441">source</a><h4 class="code-header">pub fn <a href="#method.build" class="fn">build</a>(self) -&gt; <a class="type" href="../type.Result.html" title="type iceberg::Result">Result</a>&lt;<a class="struct" href="struct.PartitionSpec.html" title="struct iceberg::spec::PartitionSpec">PartitionSpec</a>&gt;< [...]
+</div></details></div></details></div><h2 id="trait-implementations" class="section-header">Trait Implementations<a href="#trait-implementations" class="anchor">§</a></h2><div id="trait-implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-Debug-for-PartitionSpecBuilder%3C'a%3E" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#328">source</a><a href="#impl-Debug-for-PartitionSpecBuilder%3C'a%3E" class="anchor [...]
     T: 'static + ?<a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.type_id" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/nightly/src/core/any.rs.html#141">source</a><a href="#method.type_id" class="anchor">§</a><h4 class="code-header">fn <a href [...]
     T: ?<a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/nightly/src/core/borrow.rs.html#210">source</a><a href="#method.borrow" class="anchor">§</a><h4 class="code-header">fn <a href="https:/ [...]
     T: ?<a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow_mut" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/nightly/src/core/borrow.rs.html#217">source</a><a href="#method.borrow_mut" class="anchor">§</a><h4 class="code-header">fn <a href= [...]
diff --git a/api/iceberg/spec/struct.UnboundPartitionField.html b/api/iceberg/spec/struct.UnboundPartitionField.html
index 6b73c41b..66db7f4f 100644
--- a/api/iceberg/spec/struct.UnboundPartitionField.html
+++ b/api/iceberg/spec/struct.UnboundPartitionField.html
@@ -1,4 +1,4 @@
-<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Unbound partition field can be built without a schema and later bound to a schema."><title>UnboundPartitionField in iceberg::spec - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,Fira [...]
+<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Unbound partition field can be built without a schema and later bound to a schema."><title>UnboundPartitionField in iceberg::spec - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,Fira [...]
     pub source_id: <a class="primitive" href="https://doc.rust-lang.org/nightly/std/primitive.i32.html">i32</a>,
     pub field_id: <a class="enum" href="https://doc.rust-lang.org/nightly/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="primitive" href="https://doc.rust-lang.org/nightly/std/primitive.i32.html">i32</a>&gt;,
     pub name: <a class="struct" href="https://doc.rust-lang.org/nightly/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>,
@@ -9,14 +9,14 @@
 In v2 table metadata, it is unique across all partition specs.</p>
 </div><span id="structfield.name" class="structfield section-header"><a href="#structfield.name" class="anchor field">§</a><code>name: <a class="struct" href="https://doc.rust-lang.org/nightly/alloc/string/struct.String.html" title="struct alloc::string::String">String</a></code></span><div class="docblock"><p>A partition name.</p>
 </div><span id="structfield.transform" class="structfield section-header"><a href="#structfield.transform" class="anchor field">§</a><code>transform: <a class="enum" href="enum.Transform.html" title="enum iceberg::spec::Transform">Transform</a></code></span><div class="docblock"><p>A transform that is applied to the source column to produce a partition value.</p>
-</div><h2 id="implementations" class="section-header">Implementations<a href="#implementations" class="anchor">§</a></h2><div id="implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-UnboundPartitionField" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#129">source</a><a href="#impl-UnboundPartitionField" class="anchor">§</a><h3 class="code-header">impl <a class="struct" href="struct.UnboundPartitionField.h [...]
+</div><h2 id="implementations" class="section-header">Implementations<a href="#implementations" class="anchor">§</a></h2><div id="implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-UnboundPartitionField" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#183">source</a><a href="#impl-UnboundPartitionField" class="anchor">§</a><h3 class="code-header">impl <a class="struct" href="struct.UnboundPartitionField.h [...]
 On the builder, call <code>.source_id(...)</code>, <code>.field_id(...)</code>(optional), <code>.name(...)</code>, <code>.transform(...)</code> to set the values of the fields.
 Finally, call <code>.build()</code> to create the instance of <code>UnboundPartitionField</code>.</p>
-</div></details></div></details></div><h2 id="trait-implementations" class="section-header">Trait Implementations<a href="#trait-implementations" class="anchor">§</a></h2><div id="trait-implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-Clone-for-UnboundPartitionField" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#129">source</a><a href="#impl-Clone-for-UnboundPartitionField" class="anchor">§</a><h3 cla [...]
-    __D: <a class="trait" href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserializer.html" title="trait serde::de::Deserializer">Deserializer</a>&lt;'de&gt;,</div></h4></section></summary><div class='docblock'>Deserialize this value from the given Serde deserializer. <a href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserialize.html#tymethod.deserialize">Read more</a></div></details></div></details><details class="toggle implementors-toggle" open><summary><section id="impl-From% [...]
+</div></details></div></details></div><h2 id="trait-implementations" class="section-header">Trait Implementations<a href="#trait-implementations" class="anchor">§</a></h2><div id="trait-implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-Clone-for-UnboundPartitionField" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#183">source</a><a href="#impl-Clone-for-UnboundPartitionField" class="anchor">§</a><h3 cla [...]
+    __D: <a class="trait" href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserializer.html" title="trait serde::de::Deserializer">Deserializer</a>&lt;'de&gt;,</div></h4></section></summary><div class='docblock'>Deserialize this value from the given Serde deserializer. <a href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserialize.html#tymethod.deserialize">Read more</a></div></details></div></details><details class="toggle implementors-toggle" open><summary><section id="impl-From% [...]
 by <code>==</code>.</div></details><details class="toggle method-toggle" open><summary><section id="method.ne" class="method trait-impl"><span class="rightside"><span class="since" title="Stable since Rust version 1.0.0">1.0.0</span> · <a class="src" href="https://doc.rust-lang.org/nightly/src/core/cmp.rs.html#263">source</a></span><a href="#method.ne" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/nightly/core/cmp/trait.PartialEq.html#method.ne" class= [...]
-sufficient, and should not be overridden without very good reason.</div></details></div></details><details class="toggle implementors-toggle" open><summary><section id="impl-Serialize-for-UnboundPartitionField" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#129">source</a><a href="#impl-Serialize-for-UnboundPartitionField" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serialize.h [...]
-    __S: <a class="trait" href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serializer.html" title="trait serde::ser::Serializer">Serializer</a>,</div></h4></section></summary><div class='docblock'>Serialize this value into the given Serde serializer. <a href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serialize.html#tymethod.serialize">Read more</a></div></details></div></details><section id="impl-Eq-for-UnboundPartitionField" class="impl"><a class="src rightside" href="../../src/i [...]
+sufficient, and should not be overridden without very good reason.</div></details></div></details><details class="toggle implementors-toggle" open><summary><section id="impl-Serialize-for-UnboundPartitionField" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#183">source</a><a href="#impl-Serialize-for-UnboundPartitionField" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serialize.h [...]
+    __S: <a class="trait" href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serializer.html" title="trait serde::ser::Serializer">Serializer</a>,</div></h4></section></summary><div class='docblock'>Serialize this value into the given Serde serializer. <a href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serialize.html#tymethod.serialize">Read more</a></div></details></div></details><section id="impl-Eq-for-UnboundPartitionField" class="impl"><a class="src rightside" href="../../src/i [...]
     T: 'static + ?<a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.type_id" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/nightly/src/core/any.rs.html#141">source</a><a href="#method.type_id" class="anchor">§</a><h4 class="code-header">fn <a href [...]
     T: ?<a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/nightly/src/core/borrow.rs.html#210">source</a><a href="#method.borrow" class="anchor">§</a><h4 class="code-header">fn <a href="https:/ [...]
     T: ?<a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow_mut" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/nightly/src/core/borrow.rs.html#217">source</a><a href="#method.borrow_mut" class="anchor">§</a><h4 class="code-header">fn <a href= [...]
diff --git a/api/iceberg/spec/struct.UnboundPartitionSpec.html b/api/iceberg/spec/struct.UnboundPartitionSpec.html
index e1fb63f4..eab61e2b 100644
--- a/api/iceberg/spec/struct.UnboundPartitionSpec.html
+++ b/api/iceberg/spec/struct.UnboundPartitionSpec.html
@@ -1,13 +1,14 @@
-<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Unbound partition spec can be built without a schema and later bound to a schema."><title>UnboundPartitionSpec in iceberg::spec - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,FiraSa [...]
-</div></details><h2 id="implementations" class="section-header">Implementations<a href="#implementations" class="anchor">§</a></h2><div id="implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-UnboundPartitionSpec" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#154-174">source</a><a href="#impl-UnboundPartitionSpec" class="anchor">§</a><h3 class="code-header">impl <a class="struct" href="struct.UnboundPart [...]
-</div></details><details class="toggle method-toggle" open><summary><section id="method.bind" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#161-163">source</a><h4 class="code-header">pub fn <a href="#method.bind" class="fn">bind</a>(self, schema: &amp;<a class="struct" href="struct.Schema.html" title="struct iceberg::spec::Schema">Schema</a>) -&gt; <a class="type" href="../type.Result.html" title="type iceberg::Result">Result</a>&lt;<a class="stru [...]
-</div></details><details class="toggle method-toggle" open><summary><section id="method.spec_id" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#166-168">source</a><h4 class="code-header">pub fn <a href="#method.spec_id" class="fn">spec_id</a>(&amp;self) -&gt; <a class="enum" href="https://doc.rust-lang.org/nightly/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="primitive" href="https://doc.rust-lang.org/night [...]
-</div></details><details class="toggle method-toggle" open><summary><section id="method.fields" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#171-173">source</a><h4 class="code-header">pub fn <a href="#method.fields" class="fn">fields</a>(&amp;self) -&gt; &amp;[<a class="struct" href="struct.UnboundPartitionField.html" title="struct iceberg::spec::UnboundPartitionField">UnboundPartitionField</a>]</h4></section></summary><div class="docblock"><p>Fi [...]
-</div></details></div></details></div><h2 id="trait-implementations" class="section-header">Trait Implementations<a href="#trait-implementations" class="anchor">§</a></h2><div id="trait-implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-Clone-for-UnboundPartitionSpec" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#145">source</a><a href="#impl-Clone-for-UnboundPartitionSpec" class="anchor">§</a><h3 class [...]
-    __D: <a class="trait" href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserializer.html" title="trait serde::de::Deserializer">Deserializer</a>&lt;'de&gt;,</div></h4></section></summary><div class='docblock'>Deserialize this value from the given Serde deserializer. <a href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserialize.html#tymethod.deserialize">Read more</a></div></details></div></details><details class="toggle implementors-toggle" open><summary><section id="impl-From% [...]
+<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Unbound partition spec can be built without a schema and later bound to a schema."><title>UnboundPartitionSpec in iceberg::spec - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,FiraSa [...]
+</div></details><h2 id="implementations" class="section-header">Implementations<a href="#implementations" class="anchor">§</a></h2><div id="implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-UnboundPartitionSpec" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#208-236">source</a><a href="#impl-UnboundPartitionSpec" class="anchor">§</a><h3 class="code-header">impl <a class="struct" href="struct.UnboundPart [...]
+</div></details><details class="toggle method-toggle" open><summary><section id="method.bind" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#215-217">source</a><h4 class="code-header">pub fn <a href="#method.bind" class="fn">bind</a>(self, schema: &amp;<a class="struct" href="struct.Schema.html" title="struct iceberg::spec::Schema">Schema</a>) -&gt; <a class="type" href="../type.Result.html" title="type iceberg::Result">Result</a>&lt;<a class="stru [...]
+</div></details><details class="toggle method-toggle" open><summary><section id="method.spec_id" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#220-222">source</a><h4 class="code-header">pub fn <a href="#method.spec_id" class="fn">spec_id</a>(&amp;self) -&gt; <a class="enum" href="https://doc.rust-lang.org/nightly/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="primitive" href="https://doc.rust-lang.org/night [...]
+</div></details><details class="toggle method-toggle" open><summary><section id="method.fields" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#225-227">source</a><h4 class="code-header">pub fn <a href="#method.fields" class="fn">fields</a>(&amp;self) -&gt; &amp;[<a class="struct" href="struct.UnboundPartitionField.html" title="struct iceberg::spec::UnboundPartitionField">UnboundPartitionField</a>]</h4></section></summary><div class="docblock"><p>Fi [...]
+</div></details><details class="toggle method-toggle" open><summary><section id="method.with_spec_id" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#230-235">source</a><h4 class="code-header">pub fn <a href="#method.with_spec_id" class="fn">with_spec_id</a>(self, spec_id: <a class="primitive" href="https://doc.rust-lang.org/nightly/std/primitive.i32.html">i32</a>) -&gt; Self</h4></section></summary><div class="docblock"><p>Change the spec id of the [...]
+</div></details></div></details></div><h2 id="trait-implementations" class="section-header">Trait Implementations<a href="#trait-implementations" class="anchor">§</a></h2><div id="trait-implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-Clone-for-UnboundPartitionSpec" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#199">source</a><a href="#impl-Clone-for-UnboundPartitionSpec" class="anchor">§</a><h3 class [...]
+    __D: <a class="trait" href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserializer.html" title="trait serde::de::Deserializer">Deserializer</a>&lt;'de&gt;,</div></h4></section></summary><div class='docblock'>Deserialize this value from the given Serde deserializer. <a href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserialize.html#tymethod.deserialize">Read more</a></div></details></div></details><details class="toggle implementors-toggle" open><summary><section id="impl-From% [...]
 by <code>==</code>.</div></details><details class="toggle method-toggle" open><summary><section id="method.ne" class="method trait-impl"><span class="rightside"><span class="since" title="Stable since Rust version 1.0.0">1.0.0</span> · <a class="src" href="https://doc.rust-lang.org/nightly/src/core/cmp.rs.html#263">source</a></span><a href="#method.ne" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/nightly/core/cmp/trait.PartialEq.html#method.ne" class= [...]
-sufficient, and should not be overridden without very good reason.</div></details></div></details><details class="toggle implementors-toggle" open><summary><section id="impl-Serialize-for-UnboundPartitionSpec" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#145">source</a><a href="#impl-Serialize-for-UnboundPartitionSpec" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serialize.htm [...]
-    __S: <a class="trait" href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serializer.html" title="trait serde::ser::Serializer">Serializer</a>,</div></h4></section></summary><div class='docblock'>Serialize this value into the given Serde serializer. <a href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serialize.html#tymethod.serialize">Read more</a></div></details></div></details><section id="impl-Eq-for-UnboundPartitionSpec" class="impl"><a class="src rightside" href="../../src/ic [...]
+sufficient, and should not be overridden without very good reason.</div></details></div></details><details class="toggle implementors-toggle" open><summary><section id="impl-Serialize-for-UnboundPartitionSpec" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#199">source</a><a href="#impl-Serialize-for-UnboundPartitionSpec" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serialize.htm [...]
+    __S: <a class="trait" href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serializer.html" title="trait serde::ser::Serializer">Serializer</a>,</div></h4></section></summary><div class='docblock'>Serialize this value into the given Serde serializer. <a href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serialize.html#tymethod.serialize">Read more</a></div></details></div></details><section id="impl-Eq-for-UnboundPartitionSpec" class="impl"><a class="src rightside" href="../../src/ic [...]
     T: 'static + ?<a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.type_id" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/nightly/src/core/any.rs.html#141">source</a><a href="#method.type_id" class="anchor">§</a><h4 class="code-header">fn <a href [...]
     T: ?<a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/nightly/src/core/borrow.rs.html#210">source</a><a href="#method.borrow" class="anchor">§</a><h4 class="code-header">fn <a href="https:/ [...]
     T: ?<a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow_mut" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/nightly/src/core/borrow.rs.html#217">source</a><a href="#method.borrow_mut" class="anchor">§</a><h4 class="code-header">fn <a href= [...]
diff --git a/api/iceberg/spec/struct.UnboundPartitionSpecBuilder.html b/api/iceberg/spec/struct.UnboundPartitionSpecBuilder.html
index fb78ec24..87ec0a14 100644
--- a/api/iceberg/spec/struct.UnboundPartitionSpecBuilder.html
+++ b/api/iceberg/spec/struct.UnboundPartitionSpecBuilder.html
@@ -1,18 +1,18 @@
-<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Create a new UnboundPartitionSpec"><title>UnboundPartitionSpecBuilder in iceberg::spec - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,FiraSans-Regular-018c141bf0843ffd.woff2,FiraSan [...]
-</div></details><h2 id="implementations" class="section-header">Implementations<a href="#implementations" class="anchor">§</a></h2><div id="implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-UnboundPartitionSpecBuilder" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#203-263">source</a><a href="#impl-UnboundPartitionSpecBuilder" class="anchor">§</a><h3 class="code-header">impl <a class="struct" href="stru [...]
-</div></details><details class="toggle method-toggle" open><summary><section id="method.with_spec_id" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#213-216">source</a><h4 class="code-header">pub fn <a href="#method.with_spec_id" class="fn">with_spec_id</a>(self, spec_id: <a class="primitive" href="https://doc.rust-lang.org/nightly/std/primitive.i32.html">i32</a>) -&gt; Self</h4></section></summary><div class="docblock"><p>Set the spec id for the p [...]
-</div></details><details class="toggle method-toggle" open><summary><section id="method.add_partition_field" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#219-232">source</a><h4 class="code-header">pub fn <a href="#method.add_partition_field" class="fn">add_partition_field</a>(
+<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Create a new UnboundPartitionSpec"><title>UnboundPartitionSpecBuilder in iceberg::spec - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,FiraSans-Regular-018c141bf0843ffd.woff2,FiraSan [...]
+</div></details><h2 id="implementations" class="section-header">Implementations<a href="#implementations" class="anchor">§</a></h2><div id="implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-UnboundPartitionSpecBuilder" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#265-325">source</a><a href="#impl-UnboundPartitionSpecBuilder" class="anchor">§</a><h3 class="code-header">impl <a class="struct" href="stru [...]
+</div></details><details class="toggle method-toggle" open><summary><section id="method.with_spec_id" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#275-278">source</a><h4 class="code-header">pub fn <a href="#method.with_spec_id" class="fn">with_spec_id</a>(self, spec_id: <a class="primitive" href="https://doc.rust-lang.org/nightly/std/primitive.i32.html">i32</a>) -&gt; Self</h4></section></summary><div class="docblock"><p>Set the spec id for the p [...]
+</div></details><details class="toggle method-toggle" open><summary><section id="method.add_partition_field" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#281-294">source</a><h4 class="code-header">pub fn <a href="#method.add_partition_field" class="fn">add_partition_field</a>(
     self,
     source_id: <a class="primitive" href="https://doc.rust-lang.org/nightly/std/primitive.i32.html">i32</a>,
     target_name: impl <a class="trait" href="https://doc.rust-lang.org/nightly/alloc/string/trait.ToString.html" title="trait alloc::string::ToString">ToString</a>,
     transformation: <a class="enum" href="enum.Transform.html" title="enum iceberg::spec::Transform">Transform</a>,
 ) -&gt; <a class="type" href="../type.Result.html" title="type iceberg::Result">Result</a>&lt;Self&gt;</h4></section></summary><div class="docblock"><p>Add a new partition field to the partition spec from an unbound partition field.</p>
-</div></details><details class="toggle method-toggle" open><summary><section id="method.add_partition_fields" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#235-244">source</a><h4 class="code-header">pub fn <a href="#method.add_partition_fields" class="fn">add_partition_fields</a>(
+</div></details><details class="toggle method-toggle" open><summary><section id="method.add_partition_fields" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#297-306">source</a><h4 class="code-header">pub fn <a href="#method.add_partition_fields" class="fn">add_partition_fields</a>(
     self,
     fields: impl <a class="trait" href="https://doc.rust-lang.org/nightly/core/iter/traits/collect/trait.IntoIterator.html" title="trait core::iter::traits::collect::IntoIterator">IntoIterator</a>&lt;Item = <a class="struct" href="struct.UnboundPartitionField.html" title="struct iceberg::spec::UnboundPartitionField">UnboundPartitionField</a>&gt;,
 ) -&gt; <a class="type" href="../type.Result.html" title="type iceberg::Result">Result</a>&lt;Self&gt;</h4></section></summary><div class="docblock"><p>Add multiple partition fields to the partition spec.</p>
-</div></details><details class="toggle method-toggle" open><summary><section id="method.build" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#257-262">source</a><h4 class="code-header">pub fn <a href="#method.build" class="fn">build</a>(self) -&gt; <a class="struct" href="struct.UnboundPartitionSpec.html" title="struct iceberg::spec::UnboundPartitionSpec">UnboundPartitionSpec</a></h4></section></summary><div class="docblock"><p>Build the unbound pa [...]
-</div></details></div></details></div><h2 id="trait-implementations" class="section-header">Trait Implementations<a href="#trait-implementations" class="anchor">§</a></h2><div id="trait-implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-Debug-for-UnboundPartitionSpecBuilder" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#197">source</a><a href="#impl-Debug-for-UnboundPartitionSpecBuilder" class="anchor"> [...]
+</div></details><details class="toggle method-toggle" open><summary><section id="method.build" class="method"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#319-324">source</a><h4 class="code-header">pub fn <a href="#method.build" class="fn">build</a>(self) -&gt; <a class="struct" href="struct.UnboundPartitionSpec.html" title="struct iceberg::spec::UnboundPartitionSpec">UnboundPartitionSpec</a></h4></section></summary><div class="docblock"><p>Build the unbound pa [...]
+</div></details></div></details></div><h2 id="trait-implementations" class="section-header">Trait Implementations<a href="#trait-implementations" class="anchor">§</a></h2><div id="trait-implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-Debug-for-UnboundPartitionSpecBuilder" class="impl"><a class="src rightside" href="../../src/iceberg/spec/partition.rs.html#259">source</a><a href="#impl-Debug-for-UnboundPartitionSpecBuilder" class="anchor"> [...]
     T: 'static + ?<a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.type_id" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/nightly/src/core/any.rs.html#141">source</a><a href="#method.type_id" class="anchor">§</a><h4 class="code-header">fn <a href [...]
     T: ?<a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/nightly/src/core/borrow.rs.html#210">source</a><a href="#method.borrow" class="anchor">§</a><h4 class="code-header">fn <a href="https:/ [...]
     T: ?<a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow_mut" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/nightly/src/core/borrow.rs.html#217">source</a><a href="#method.borrow_mut" class="anchor">§</a><h4 class="code-header">fn <a href= [...]
diff --git a/api/iceberg/spec/type.UnboundPartitionSpecRef.html b/api/iceberg/spec/type.UnboundPartitionSpecRef.html
index bb8c5b4a..01ab5336 100644
--- a/api/iceberg/spec/type.UnboundPartitionSpecRef.html
+++ b/api/iceberg/spec/type.UnboundPartitionSpecRef.html
@@ -1,2 +1,2 @@
-<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Reference to `UnboundPartitionSpec`."><title>UnboundPartitionSpecRef in iceberg::spec - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,FiraSans-Regular-018c141bf0843ffd.woff2,FiraSans [...]
+<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Reference to `UnboundPartitionSpec`."><title>UnboundPartitionSpecRef in iceberg::spec - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,FiraSans-Regular-018c141bf0843ffd.woff2,FiraSans [...]
 </div></details><h2 id="aliased-type" class="section-header">Aliased Type<a href="#aliased-type" class="anchor">§</a></h2><pre class="rust item-decl"><code>struct UnboundPartitionSpecRef { <span class="comment">/* private fields */</span> }</code></pre><script src="../../type.impl/alloc/sync/struct.Arc.js" data-self-path="iceberg::spec::partition::UnboundPartitionSpecRef" async></script></section></div></main></body></html>
\ No newline at end of file
diff --git a/api/search-index.js b/api/search-index.js
index 1420d912..313a1da4 100644
--- a/api/search-index.js
+++ b/api/search-index.js
@@ -1,5 +1,5 @@
 var searchIndex = new Map(JSON.parse('[\
-["iceberg",{"t":"PPPPPKPPPPPFGPPPFFPPPPPPIPPPPPPFFFGGPPPFNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMMOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMMQNNNNNNNNNNNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNNNNNNNNNNNNNNNNNNNNNCNMMMOONNNOOONOMNNNNNONOOMOCOONNNNONCOCMNNNNNNNNNNCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMMNNNNNNNNNNNNNCOOOOOOOOOOOOOOOOOOOOOOOOOFFKRRNNNNNNNNHNNNNNNNNNNNNNNNNNNNNNNNNNNNMMMNMHMNNNNNNNNNNNNPPPPPPPPFKRGFIPPPPPPPPFPPPPPPPPPGGFPPFPIPPFNNMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN [...]
+["iceberg",{"t":"PPPPPKPPPPPFGPPPFFPPPPPPIPPPPPPFFFGGPPPFNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMMOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMMQNNNNNNNNNNNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNNNNNNNNNNNNNNNNNNNNNCNMMMOONNNOOONOMNNNNNONOOMOCOONNNNONCOCMNNNNNNNNNNCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMMNNNNNNNNNNNNNCOOOOOOOOOOOOOOOOOOOOOOOOOFFKRRNNNNNNNNHNNNNNNNNNNNNNNNNNNNNNNNNNNNMMMNMHMNNNNNNNNNNNNPPPPPPPPFKRGFIPPPPPPPPFPPPPPPPPPGGFPPFPIPPFNNMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN [...]
 ["iceberg_catalog_glue",{"t":"SSSSSFFNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNQ","n":["AWS_ACCESS_KEY_ID","AWS_PROFILE_NAME","AWS_REGION_NAME","AWS_SECRET_ACCESS_KEY","AWS_SESSION_TOKEN","GlueCatalog","GlueCatalogConfig","borrow","borrow","borrow_mut","borrow_mut","builder","create_namespace","create_table","deref","deref","deref_mut","deref_mut","drop","drop","drop_namespace","drop_table","file_io","fmt","fmt","from","from","get_namespace","init","init","into","into","into_shared","i [...]
 ["iceberg_catalog_hms",{"t":"PPFFGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN","n":["Buffered","Framed","HmsCatalog","HmsCatalogConfig","HmsThriftTransport","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","builder","create_namespace","create_table","default","deref","deref","deref","deref_mut","deref_mut","deref_mut","drop","drop","drop","drop_namespace","drop_table","file_io","fmt","fmt","fmt","from","from","from","get_namespace","init","init","init","into [...]
 ["iceberg_catalog_memory",{"t":"FNNNNNNNNNNNNNNNNNNNNNNNNNNN","n":["MemoryCatalog","borrow","borrow_mut","create_namespace","create_table","deref","deref_mut","drop","drop_namespace","drop_table","fmt","from","get_namespace","init","into","list_namespaces","list_tables","load_table","namespace_exists","new","rename_table","table_exists","try_from","try_into","type_id","update_namespace","update_table","vzip"],"q":[[0,"iceberg_catalog_memory"],[28,"iceberg_catalog_memory::catalog"],[29,"i [...]
diff --git a/api/search.desc/iceberg/iceberg-desc-0-.js b/api/search.desc/iceberg/iceberg-desc-0-.js
index 05663348..90017a7a 100644
--- a/api/search.desc/iceberg/iceberg-desc-0-.js
+++ b/api/search.desc/iceberg/iceberg-desc-0-.js
@@ -1 +1 @@
-searchState.loadedDescShard("iceberg", 0, "Apache Iceberg Official Native Rust Implementation\nAdd a new schema to the table\nAdd snapshot to table.\nAdd sort order to table.\nAdd a new partition spec to the table\nAssign a new UUID to the table\nThe catalog API for Iceberg Rust.\nThe table’s current schema id must match the requirement.\nIceberg data is invalid.\nThe table’s default sort order id must match the …\nThe table’s default spec id must match the requirement.\nContains the err [...]
\ No newline at end of file
+searchState.loadedDescShard("iceberg", 0, "Apache Iceberg Official Native Rust Implementation\nAdd a new schema to the table\nAdd snapshot to table.\nAdd sort order to table.\nAdd a new partition spec to the table\nAssign a new UUID to the table\nThe catalog API for Iceberg Rust.\nThe table’s current schema id must match the requirement.\nIceberg data is invalid.\nThe table’s default sort order id must match the …\nThe table’s default spec id must match the requirement.\nContains the err [...]
\ No newline at end of file
diff --git a/api/src/iceberg/spec/partition.rs.html b/api/src/iceberg/spec/partition.rs.html
index c697f1f1..e1b3793e 100644
--- a/api/src/iceberg/spec/partition.rs.html
+++ b/api/src/iceberg/spec/partition.rs.html
@@ -1264,6 +1264,418 @@
 <a href="#1264" id="1264">1264</a>
 <a href="#1265" id="1265">1265</a>
 <a href="#1266" id="1266">1266</a>
+<a href="#1267" id="1267">1267</a>
+<a href="#1268" id="1268">1268</a>
+<a href="#1269" id="1269">1269</a>
+<a href="#1270" id="1270">1270</a>
+<a href="#1271" id="1271">1271</a>
+<a href="#1272" id="1272">1272</a>
+<a href="#1273" id="1273">1273</a>
+<a href="#1274" id="1274">1274</a>
+<a href="#1275" id="1275">1275</a>
+<a href="#1276" id="1276">1276</a>
+<a href="#1277" id="1277">1277</a>
+<a href="#1278" id="1278">1278</a>
+<a href="#1279" id="1279">1279</a>
+<a href="#1280" id="1280">1280</a>
+<a href="#1281" id="1281">1281</a>
+<a href="#1282" id="1282">1282</a>
+<a href="#1283" id="1283">1283</a>
+<a href="#1284" id="1284">1284</a>
+<a href="#1285" id="1285">1285</a>
+<a href="#1286" id="1286">1286</a>
+<a href="#1287" id="1287">1287</a>
+<a href="#1288" id="1288">1288</a>
+<a href="#1289" id="1289">1289</a>
+<a href="#1290" id="1290">1290</a>
+<a href="#1291" id="1291">1291</a>
+<a href="#1292" id="1292">1292</a>
+<a href="#1293" id="1293">1293</a>
+<a href="#1294" id="1294">1294</a>
+<a href="#1295" id="1295">1295</a>
+<a href="#1296" id="1296">1296</a>
+<a href="#1297" id="1297">1297</a>
+<a href="#1298" id="1298">1298</a>
+<a href="#1299" id="1299">1299</a>
+<a href="#1300" id="1300">1300</a>
+<a href="#1301" id="1301">1301</a>
+<a href="#1302" id="1302">1302</a>
+<a href="#1303" id="1303">1303</a>
+<a href="#1304" id="1304">1304</a>
+<a href="#1305" id="1305">1305</a>
+<a href="#1306" id="1306">1306</a>
+<a href="#1307" id="1307">1307</a>
+<a href="#1308" id="1308">1308</a>
+<a href="#1309" id="1309">1309</a>
+<a href="#1310" id="1310">1310</a>
+<a href="#1311" id="1311">1311</a>
+<a href="#1312" id="1312">1312</a>
+<a href="#1313" id="1313">1313</a>
+<a href="#1314" id="1314">1314</a>
+<a href="#1315" id="1315">1315</a>
+<a href="#1316" id="1316">1316</a>
+<a href="#1317" id="1317">1317</a>
+<a href="#1318" id="1318">1318</a>
+<a href="#1319" id="1319">1319</a>
+<a href="#1320" id="1320">1320</a>
+<a href="#1321" id="1321">1321</a>
+<a href="#1322" id="1322">1322</a>
+<a href="#1323" id="1323">1323</a>
+<a href="#1324" id="1324">1324</a>
+<a href="#1325" id="1325">1325</a>
+<a href="#1326" id="1326">1326</a>
+<a href="#1327" id="1327">1327</a>
+<a href="#1328" id="1328">1328</a>
+<a href="#1329" id="1329">1329</a>
+<a href="#1330" id="1330">1330</a>
+<a href="#1331" id="1331">1331</a>
+<a href="#1332" id="1332">1332</a>
+<a href="#1333" id="1333">1333</a>
+<a href="#1334" id="1334">1334</a>
+<a href="#1335" id="1335">1335</a>
+<a href="#1336" id="1336">1336</a>
+<a href="#1337" id="1337">1337</a>
+<a href="#1338" id="1338">1338</a>
+<a href="#1339" id="1339">1339</a>
+<a href="#1340" id="1340">1340</a>
+<a href="#1341" id="1341">1341</a>
+<a href="#1342" id="1342">1342</a>
+<a href="#1343" id="1343">1343</a>
+<a href="#1344" id="1344">1344</a>
+<a href="#1345" id="1345">1345</a>
+<a href="#1346" id="1346">1346</a>
+<a href="#1347" id="1347">1347</a>
+<a href="#1348" id="1348">1348</a>
+<a href="#1349" id="1349">1349</a>
+<a href="#1350" id="1350">1350</a>
+<a href="#1351" id="1351">1351</a>
+<a href="#1352" id="1352">1352</a>
+<a href="#1353" id="1353">1353</a>
+<a href="#1354" id="1354">1354</a>
+<a href="#1355" id="1355">1355</a>
+<a href="#1356" id="1356">1356</a>
+<a href="#1357" id="1357">1357</a>
+<a href="#1358" id="1358">1358</a>
+<a href="#1359" id="1359">1359</a>
+<a href="#1360" id="1360">1360</a>
+<a href="#1361" id="1361">1361</a>
+<a href="#1362" id="1362">1362</a>
+<a href="#1363" id="1363">1363</a>
+<a href="#1364" id="1364">1364</a>
+<a href="#1365" id="1365">1365</a>
+<a href="#1366" id="1366">1366</a>
+<a href="#1367" id="1367">1367</a>
+<a href="#1368" id="1368">1368</a>
+<a href="#1369" id="1369">1369</a>
+<a href="#1370" id="1370">1370</a>
+<a href="#1371" id="1371">1371</a>
+<a href="#1372" id="1372">1372</a>
+<a href="#1373" id="1373">1373</a>
+<a href="#1374" id="1374">1374</a>
+<a href="#1375" id="1375">1375</a>
+<a href="#1376" id="1376">1376</a>
+<a href="#1377" id="1377">1377</a>
+<a href="#1378" id="1378">1378</a>
+<a href="#1379" id="1379">1379</a>
+<a href="#1380" id="1380">1380</a>
+<a href="#1381" id="1381">1381</a>
+<a href="#1382" id="1382">1382</a>
+<a href="#1383" id="1383">1383</a>
+<a href="#1384" id="1384">1384</a>
+<a href="#1385" id="1385">1385</a>
+<a href="#1386" id="1386">1386</a>
+<a href="#1387" id="1387">1387</a>
+<a href="#1388" id="1388">1388</a>
+<a href="#1389" id="1389">1389</a>
+<a href="#1390" id="1390">1390</a>
+<a href="#1391" id="1391">1391</a>
+<a href="#1392" id="1392">1392</a>
+<a href="#1393" id="1393">1393</a>
+<a href="#1394" id="1394">1394</a>
+<a href="#1395" id="1395">1395</a>
+<a href="#1396" id="1396">1396</a>
+<a href="#1397" id="1397">1397</a>
+<a href="#1398" id="1398">1398</a>
+<a href="#1399" id="1399">1399</a>
+<a href="#1400" id="1400">1400</a>
+<a href="#1401" id="1401">1401</a>
+<a href="#1402" id="1402">1402</a>
+<a href="#1403" id="1403">1403</a>
+<a href="#1404" id="1404">1404</a>
+<a href="#1405" id="1405">1405</a>
+<a href="#1406" id="1406">1406</a>
+<a href="#1407" id="1407">1407</a>
+<a href="#1408" id="1408">1408</a>
+<a href="#1409" id="1409">1409</a>
+<a href="#1410" id="1410">1410</a>
+<a href="#1411" id="1411">1411</a>
+<a href="#1412" id="1412">1412</a>
+<a href="#1413" id="1413">1413</a>
+<a href="#1414" id="1414">1414</a>
+<a href="#1415" id="1415">1415</a>
+<a href="#1416" id="1416">1416</a>
+<a href="#1417" id="1417">1417</a>
+<a href="#1418" id="1418">1418</a>
+<a href="#1419" id="1419">1419</a>
+<a href="#1420" id="1420">1420</a>
+<a href="#1421" id="1421">1421</a>
+<a href="#1422" id="1422">1422</a>
+<a href="#1423" id="1423">1423</a>
+<a href="#1424" id="1424">1424</a>
+<a href="#1425" id="1425">1425</a>
+<a href="#1426" id="1426">1426</a>
+<a href="#1427" id="1427">1427</a>
+<a href="#1428" id="1428">1428</a>
+<a href="#1429" id="1429">1429</a>
+<a href="#1430" id="1430">1430</a>
+<a href="#1431" id="1431">1431</a>
+<a href="#1432" id="1432">1432</a>
+<a href="#1433" id="1433">1433</a>
+<a href="#1434" id="1434">1434</a>
+<a href="#1435" id="1435">1435</a>
+<a href="#1436" id="1436">1436</a>
+<a href="#1437" id="1437">1437</a>
+<a href="#1438" id="1438">1438</a>
+<a href="#1439" id="1439">1439</a>
+<a href="#1440" id="1440">1440</a>
+<a href="#1441" id="1441">1441</a>
+<a href="#1442" id="1442">1442</a>
+<a href="#1443" id="1443">1443</a>
+<a href="#1444" id="1444">1444</a>
+<a href="#1445" id="1445">1445</a>
+<a href="#1446" id="1446">1446</a>
+<a href="#1447" id="1447">1447</a>
+<a href="#1448" id="1448">1448</a>
+<a href="#1449" id="1449">1449</a>
+<a href="#1450" id="1450">1450</a>
+<a href="#1451" id="1451">1451</a>
+<a href="#1452" id="1452">1452</a>
+<a href="#1453" id="1453">1453</a>
+<a href="#1454" id="1454">1454</a>
+<a href="#1455" id="1455">1455</a>
+<a href="#1456" id="1456">1456</a>
+<a href="#1457" id="1457">1457</a>
+<a href="#1458" id="1458">1458</a>
+<a href="#1459" id="1459">1459</a>
+<a href="#1460" id="1460">1460</a>
+<a href="#1461" id="1461">1461</a>
+<a href="#1462" id="1462">1462</a>
+<a href="#1463" id="1463">1463</a>
+<a href="#1464" id="1464">1464</a>
+<a href="#1465" id="1465">1465</a>
+<a href="#1466" id="1466">1466</a>
+<a href="#1467" id="1467">1467</a>
+<a href="#1468" id="1468">1468</a>
+<a href="#1469" id="1469">1469</a>
+<a href="#1470" id="1470">1470</a>
+<a href="#1471" id="1471">1471</a>
+<a href="#1472" id="1472">1472</a>
+<a href="#1473" id="1473">1473</a>
+<a href="#1474" id="1474">1474</a>
+<a href="#1475" id="1475">1475</a>
+<a href="#1476" id="1476">1476</a>
+<a href="#1477" id="1477">1477</a>
+<a href="#1478" id="1478">1478</a>
+<a href="#1479" id="1479">1479</a>
+<a href="#1480" id="1480">1480</a>
+<a href="#1481" id="1481">1481</a>
+<a href="#1482" id="1482">1482</a>
+<a href="#1483" id="1483">1483</a>
+<a href="#1484" id="1484">1484</a>
+<a href="#1485" id="1485">1485</a>
+<a href="#1486" id="1486">1486</a>
+<a href="#1487" id="1487">1487</a>
+<a href="#1488" id="1488">1488</a>
+<a href="#1489" id="1489">1489</a>
+<a href="#1490" id="1490">1490</a>
+<a href="#1491" id="1491">1491</a>
+<a href="#1492" id="1492">1492</a>
+<a href="#1493" id="1493">1493</a>
+<a href="#1494" id="1494">1494</a>
+<a href="#1495" id="1495">1495</a>
+<a href="#1496" id="1496">1496</a>
+<a href="#1497" id="1497">1497</a>
+<a href="#1498" id="1498">1498</a>
+<a href="#1499" id="1499">1499</a>
+<a href="#1500" id="1500">1500</a>
+<a href="#1501" id="1501">1501</a>
+<a href="#1502" id="1502">1502</a>
+<a href="#1503" id="1503">1503</a>
+<a href="#1504" id="1504">1504</a>
+<a href="#1505" id="1505">1505</a>
+<a href="#1506" id="1506">1506</a>
+<a href="#1507" id="1507">1507</a>
+<a href="#1508" id="1508">1508</a>
+<a href="#1509" id="1509">1509</a>
+<a href="#1510" id="1510">1510</a>
+<a href="#1511" id="1511">1511</a>
+<a href="#1512" id="1512">1512</a>
+<a href="#1513" id="1513">1513</a>
+<a href="#1514" id="1514">1514</a>
+<a href="#1515" id="1515">1515</a>
+<a href="#1516" id="1516">1516</a>
+<a href="#1517" id="1517">1517</a>
+<a href="#1518" id="1518">1518</a>
+<a href="#1519" id="1519">1519</a>
+<a href="#1520" id="1520">1520</a>
+<a href="#1521" id="1521">1521</a>
+<a href="#1522" id="1522">1522</a>
+<a href="#1523" id="1523">1523</a>
+<a href="#1524" id="1524">1524</a>
+<a href="#1525" id="1525">1525</a>
+<a href="#1526" id="1526">1526</a>
+<a href="#1527" id="1527">1527</a>
+<a href="#1528" id="1528">1528</a>
+<a href="#1529" id="1529">1529</a>
+<a href="#1530" id="1530">1530</a>
+<a href="#1531" id="1531">1531</a>
+<a href="#1532" id="1532">1532</a>
+<a href="#1533" id="1533">1533</a>
+<a href="#1534" id="1534">1534</a>
+<a href="#1535" id="1535">1535</a>
+<a href="#1536" id="1536">1536</a>
+<a href="#1537" id="1537">1537</a>
+<a href="#1538" id="1538">1538</a>
+<a href="#1539" id="1539">1539</a>
+<a href="#1540" id="1540">1540</a>
+<a href="#1541" id="1541">1541</a>
+<a href="#1542" id="1542">1542</a>
+<a href="#1543" id="1543">1543</a>
+<a href="#1544" id="1544">1544</a>
+<a href="#1545" id="1545">1545</a>
+<a href="#1546" id="1546">1546</a>
+<a href="#1547" id="1547">1547</a>
+<a href="#1548" id="1548">1548</a>
+<a href="#1549" id="1549">1549</a>
+<a href="#1550" id="1550">1550</a>
+<a href="#1551" id="1551">1551</a>
+<a href="#1552" id="1552">1552</a>
+<a href="#1553" id="1553">1553</a>
+<a href="#1554" id="1554">1554</a>
+<a href="#1555" id="1555">1555</a>
+<a href="#1556" id="1556">1556</a>
+<a href="#1557" id="1557">1557</a>
+<a href="#1558" id="1558">1558</a>
+<a href="#1559" id="1559">1559</a>
+<a href="#1560" id="1560">1560</a>
+<a href="#1561" id="1561">1561</a>
+<a href="#1562" id="1562">1562</a>
+<a href="#1563" id="1563">1563</a>
+<a href="#1564" id="1564">1564</a>
+<a href="#1565" id="1565">1565</a>
+<a href="#1566" id="1566">1566</a>
+<a href="#1567" id="1567">1567</a>
+<a href="#1568" id="1568">1568</a>
+<a href="#1569" id="1569">1569</a>
+<a href="#1570" id="1570">1570</a>
+<a href="#1571" id="1571">1571</a>
+<a href="#1572" id="1572">1572</a>
+<a href="#1573" id="1573">1573</a>
+<a href="#1574" id="1574">1574</a>
+<a href="#1575" id="1575">1575</a>
+<a href="#1576" id="1576">1576</a>
+<a href="#1577" id="1577">1577</a>
+<a href="#1578" id="1578">1578</a>
+<a href="#1579" id="1579">1579</a>
+<a href="#1580" id="1580">1580</a>
+<a href="#1581" id="1581">1581</a>
+<a href="#1582" id="1582">1582</a>
+<a href="#1583" id="1583">1583</a>
+<a href="#1584" id="1584">1584</a>
+<a href="#1585" id="1585">1585</a>
+<a href="#1586" id="1586">1586</a>
+<a href="#1587" id="1587">1587</a>
+<a href="#1588" id="1588">1588</a>
+<a href="#1589" id="1589">1589</a>
+<a href="#1590" id="1590">1590</a>
+<a href="#1591" id="1591">1591</a>
+<a href="#1592" id="1592">1592</a>
+<a href="#1593" id="1593">1593</a>
+<a href="#1594" id="1594">1594</a>
+<a href="#1595" id="1595">1595</a>
+<a href="#1596" id="1596">1596</a>
+<a href="#1597" id="1597">1597</a>
+<a href="#1598" id="1598">1598</a>
+<a href="#1599" id="1599">1599</a>
+<a href="#1600" id="1600">1600</a>
+<a href="#1601" id="1601">1601</a>
+<a href="#1602" id="1602">1602</a>
+<a href="#1603" id="1603">1603</a>
+<a href="#1604" id="1604">1604</a>
+<a href="#1605" id="1605">1605</a>
+<a href="#1606" id="1606">1606</a>
+<a href="#1607" id="1607">1607</a>
+<a href="#1608" id="1608">1608</a>
+<a href="#1609" id="1609">1609</a>
+<a href="#1610" id="1610">1610</a>
+<a href="#1611" id="1611">1611</a>
+<a href="#1612" id="1612">1612</a>
+<a href="#1613" id="1613">1613</a>
+<a href="#1614" id="1614">1614</a>
+<a href="#1615" id="1615">1615</a>
+<a href="#1616" id="1616">1616</a>
+<a href="#1617" id="1617">1617</a>
+<a href="#1618" id="1618">1618</a>
+<a href="#1619" id="1619">1619</a>
+<a href="#1620" id="1620">1620</a>
+<a href="#1621" id="1621">1621</a>
+<a href="#1622" id="1622">1622</a>
+<a href="#1623" id="1623">1623</a>
+<a href="#1624" id="1624">1624</a>
+<a href="#1625" id="1625">1625</a>
+<a href="#1626" id="1626">1626</a>
+<a href="#1627" id="1627">1627</a>
+<a href="#1628" id="1628">1628</a>
+<a href="#1629" id="1629">1629</a>
+<a href="#1630" id="1630">1630</a>
+<a href="#1631" id="1631">1631</a>
+<a href="#1632" id="1632">1632</a>
+<a href="#1633" id="1633">1633</a>
+<a href="#1634" id="1634">1634</a>
+<a href="#1635" id="1635">1635</a>
+<a href="#1636" id="1636">1636</a>
+<a href="#1637" id="1637">1637</a>
+<a href="#1638" id="1638">1638</a>
+<a href="#1639" id="1639">1639</a>
+<a href="#1640" id="1640">1640</a>
+<a href="#1641" id="1641">1641</a>
+<a href="#1642" id="1642">1642</a>
+<a href="#1643" id="1643">1643</a>
+<a href="#1644" id="1644">1644</a>
+<a href="#1645" id="1645">1645</a>
+<a href="#1646" id="1646">1646</a>
+<a href="#1647" id="1647">1647</a>
+<a href="#1648" id="1648">1648</a>
+<a href="#1649" id="1649">1649</a>
+<a href="#1650" id="1650">1650</a>
+<a href="#1651" id="1651">1651</a>
+<a href="#1652" id="1652">1652</a>
+<a href="#1653" id="1653">1653</a>
+<a href="#1654" id="1654">1654</a>
+<a href="#1655" id="1655">1655</a>
+<a href="#1656" id="1656">1656</a>
+<a href="#1657" id="1657">1657</a>
+<a href="#1658" id="1658">1658</a>
+<a href="#1659" id="1659">1659</a>
+<a href="#1660" id="1660">1660</a>
+<a href="#1661" id="1661">1661</a>
+<a href="#1662" id="1662">1662</a>
+<a href="#1663" id="1663">1663</a>
+<a href="#1664" id="1664">1664</a>
+<a href="#1665" id="1665">1665</a>
+<a href="#1666" id="1666">1666</a>
+<a href="#1667" id="1667">1667</a>
+<a href="#1668" id="1668">1668</a>
+<a href="#1669" id="1669">1669</a>
+<a href="#1670" id="1670">1670</a>
+<a href="#1671" id="1671">1671</a>
+<a href="#1672" id="1672">1672</a>
+<a href="#1673" id="1673">1673</a>
+<a href="#1674" id="1674">1674</a>
+<a href="#1675" id="1675">1675</a>
+<a href="#1676" id="1676">1676</a>
+<a href="#1677" id="1677">1677</a>
+<a href="#1678" id="1678">1678</a>
 </pre></div><pre class="rust"><code><span class="comment">// Licensed to the Apache Software Foundation (ASF) under one
 // or more contributor license agreements.  See the NOTICE file
 // distributed with this work for additional information
@@ -1384,9 +1796,63 @@
     <span class="doccomment">/// Turn this partition spec into an unbound partition spec.
     ///
     /// The `field_id` is retained as `partition_id` in the unbound partition spec.
-    </span><span class="kw">pub fn </span>to_unbound(<span class="self">self</span>) -&gt; UnboundPartitionSpec {
+    </span><span class="kw">pub fn </span>into_unbound(<span class="self">self</span>) -&gt; UnboundPartitionSpec {
         <span class="self">self</span>.into()
     }
+
+    <span class="doccomment">/// Check if this partition spec is compatible with another partition spec.
+    ///
+    /// Returns true if the partition spec is equal to the other spec with partition field ids ignored and
+    /// spec_id ignored. The following must be identical:
+    /// * The number of fields
+    /// * Field order
+    /// * Field names
+    /// * Source column ids
+    /// * Transforms
+    </span><span class="kw">pub fn </span>is_compatible_with(<span class="kw-2">&amp;</span><span class="self">self</span>, other: <span class="kw-2">&amp;</span>UnboundPartitionSpec) -&gt; bool {
+        <span class="kw">if </span><span class="self">self</span>.fields.len() != other.fields.len() {
+            <span class="kw">return </span><span class="bool-val">false</span>;
+        }
+
+        <span class="kw">for </span>(this_field, other_field) <span class="kw">in </span><span class="self">self</span>.fields.iter().zip(<span class="kw-2">&amp;</span>other.fields) {
+            <span class="kw">if </span>this_field.source_id != other_field.source_id
+                || this_field.transform != other_field.transform
+                || this_field.name != other_field.name
+            {
+                <span class="kw">return </span><span class="bool-val">false</span>;
+            }
+        }
+
+        <span class="bool-val">true
+    </span>}
+
+    <span class="doccomment">/// Check if this partition spec has sequential partition ids.
+    /// Sequential ids start from 1000 and increment by 1 for each field.
+    /// This is required for spec version 1
+    </span><span class="kw">pub fn </span>has_sequential_ids(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
+        <span class="kw">for </span>(index, field) <span class="kw">in </span><span class="self">self</span>.fields.iter().enumerate() {
+            <span class="kw">let </span>expected_id = (UNPARTITIONED_LAST_ASSIGNED_ID <span class="kw">as </span>i64)
+                .checked_add(<span class="number">1</span>)
+                .and_then(|id| id.checked_add(index <span class="kw">as </span>i64))
+                .unwrap_or(i64::MAX);
+
+            <span class="kw">if </span>field.field_id <span class="kw">as </span>i64 != expected_id {
+                <span class="kw">return </span><span class="bool-val">false</span>;
+            }
+        }
+
+        <span class="bool-val">true
+    </span>}
+
+    <span class="doccomment">/// Get the highest field id in the partition spec.
+    /// If the partition spec is unpartitioned, it returns the last unpartitioned last assigned id (999).
+    </span><span class="kw">pub fn </span>highest_field_id(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; i32 {
+        <span class="self">self</span>.fields
+            .iter()
+            .map(|f| f.field_id)
+            .max()
+            .unwrap_or(UNPARTITIONED_LAST_ASSIGNED_ID)
+    }
 }
 
 <span class="doccomment">/// Reference to [`UnboundPartitionSpec`].
@@ -1437,6 +1903,14 @@
     </span><span class="kw">pub fn </span>fields(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>[UnboundPartitionField] {
         <span class="kw-2">&amp;</span><span class="self">self</span>.fields
     }
+
+    <span class="doccomment">/// Change the spec id of the partition spec
+    </span><span class="kw">pub fn </span>with_spec_id(<span class="self">self</span>, spec_id: i32) -&gt; <span class="self">Self </span>{
+        <span class="self">Self </span>{
+            spec_id: <span class="prelude-val">Some</span>(spec_id),
+            ..<span class="self">self
+        </span>}
+    }
 }
 
 <span class="kw">impl </span>From&lt;PartitionField&gt; <span class="kw">for </span>UnboundPartitionField {
@@ -2529,5 +3003,355 @@
             }]
         });
     }
+
+    <span class="attr">#[test]
+    </span><span class="kw">fn </span>test_is_compatible_with() {
+        <span class="kw">let </span>schema = Schema::builder()
+            .with_fields(<span class="macro">vec!</span>[
+                NestedField::required(<span class="number">1</span>, <span class="string">"id"</span>, Type::Primitive(<span class="kw">crate</span>::spec::PrimitiveType::Int))
+                    .into(),
+                NestedField::required(
+                    <span class="number">2</span>,
+                    <span class="string">"name"</span>,
+                    Type::Primitive(<span class="kw">crate</span>::spec::PrimitiveType::String),
+                )
+                .into(),
+            ])
+            .build()
+            .unwrap();
+
+        <span class="kw">let </span>partition_spec_1 = PartitionSpec::builder(<span class="kw-2">&amp;</span>schema)
+            .with_spec_id(<span class="number">1</span>)
+            .add_unbound_field(UnboundPartitionField {
+                source_id: <span class="number">1</span>,
+                field_id: <span class="prelude-val">None</span>,
+                name: <span class="string">"id_bucket"</span>.to_string(),
+                transform: Transform::Bucket(<span class="number">16</span>),
+            })
+            .unwrap()
+            .build()
+            .unwrap();
+
+        <span class="kw">let </span>partition_spec_2 = PartitionSpec::builder(<span class="kw-2">&amp;</span>schema)
+            .with_spec_id(<span class="number">1</span>)
+            .add_unbound_field(UnboundPartitionField {
+                source_id: <span class="number">1</span>,
+                field_id: <span class="prelude-val">None</span>,
+                name: <span class="string">"id_bucket"</span>.to_string(),
+                transform: Transform::Bucket(<span class="number">16</span>),
+            })
+            .unwrap()
+            .build()
+            .unwrap();
+
+        <span class="macro">assert!</span>(partition_spec_1.is_compatible_with(<span class="kw-2">&amp;</span>partition_spec_2.into_unbound()));
+    }
+
+    <span class="attr">#[test]
+    </span><span class="kw">fn </span>test_not_compatible_with_transform_different() {
+        <span class="kw">let </span>schema = Schema::builder()
+            .with_fields(<span class="macro">vec!</span>[NestedField::required(
+                <span class="number">1</span>,
+                <span class="string">"id"</span>,
+                Type::Primitive(<span class="kw">crate</span>::spec::PrimitiveType::Int),
+            )
+            .into()])
+            .build()
+            .unwrap();
+
+        <span class="kw">let </span>partition_spec_1 = PartitionSpec::builder(<span class="kw-2">&amp;</span>schema)
+            .with_spec_id(<span class="number">1</span>)
+            .add_unbound_field(UnboundPartitionField {
+                source_id: <span class="number">1</span>,
+                field_id: <span class="prelude-val">None</span>,
+                name: <span class="string">"id_bucket"</span>.to_string(),
+                transform: Transform::Bucket(<span class="number">16</span>),
+            })
+            .unwrap()
+            .build()
+            .unwrap();
+
+        <span class="kw">let </span>partition_spec_2 = PartitionSpec::builder(<span class="kw-2">&amp;</span>schema)
+            .with_spec_id(<span class="number">1</span>)
+            .add_unbound_field(UnboundPartitionField {
+                source_id: <span class="number">1</span>,
+                field_id: <span class="prelude-val">None</span>,
+                name: <span class="string">"id_bucket"</span>.to_string(),
+                transform: Transform::Bucket(<span class="number">32</span>),
+            })
+            .unwrap()
+            .build()
+            .unwrap();
+
+        <span class="macro">assert!</span>(!partition_spec_1.is_compatible_with(<span class="kw-2">&amp;</span>partition_spec_2.into_unbound()));
+    }
+
+    <span class="attr">#[test]
+    </span><span class="kw">fn </span>test_not_compatible_with_source_id_different() {
+        <span class="kw">let </span>schema = Schema::builder()
+            .with_fields(<span class="macro">vec!</span>[
+                NestedField::required(<span class="number">1</span>, <span class="string">"id"</span>, Type::Primitive(<span class="kw">crate</span>::spec::PrimitiveType::Int))
+                    .into(),
+                NestedField::required(
+                    <span class="number">2</span>,
+                    <span class="string">"name"</span>,
+                    Type::Primitive(<span class="kw">crate</span>::spec::PrimitiveType::String),
+                )
+                .into(),
+            ])
+            .build()
+            .unwrap();
+
+        <span class="kw">let </span>partition_spec_1 = PartitionSpec::builder(<span class="kw-2">&amp;</span>schema)
+            .with_spec_id(<span class="number">1</span>)
+            .add_unbound_field(UnboundPartitionField {
+                source_id: <span class="number">1</span>,
+                field_id: <span class="prelude-val">None</span>,
+                name: <span class="string">"id_bucket"</span>.to_string(),
+                transform: Transform::Bucket(<span class="number">16</span>),
+            })
+            .unwrap()
+            .build()
+            .unwrap();
+
+        <span class="kw">let </span>partition_spec_2 = PartitionSpec::builder(<span class="kw-2">&amp;</span>schema)
+            .with_spec_id(<span class="number">1</span>)
+            .add_unbound_field(UnboundPartitionField {
+                source_id: <span class="number">2</span>,
+                field_id: <span class="prelude-val">None</span>,
+                name: <span class="string">"id_bucket"</span>.to_string(),
+                transform: Transform::Bucket(<span class="number">16</span>),
+            })
+            .unwrap()
+            .build()
+            .unwrap();
+
+        <span class="macro">assert!</span>(!partition_spec_1.is_compatible_with(<span class="kw-2">&amp;</span>partition_spec_2.into_unbound()));
+    }
+
+    <span class="attr">#[test]
+    </span><span class="kw">fn </span>test_not_compatible_with_order_different() {
+        <span class="kw">let </span>schema = Schema::builder()
+            .with_fields(<span class="macro">vec!</span>[
+                NestedField::required(<span class="number">1</span>, <span class="string">"id"</span>, Type::Primitive(<span class="kw">crate</span>::spec::PrimitiveType::Int))
+                    .into(),
+                NestedField::required(
+                    <span class="number">2</span>,
+                    <span class="string">"name"</span>,
+                    Type::Primitive(<span class="kw">crate</span>::spec::PrimitiveType::String),
+                )
+                .into(),
+            ])
+            .build()
+            .unwrap();
+
+        <span class="kw">let </span>partition_spec_1 = PartitionSpec::builder(<span class="kw-2">&amp;</span>schema)
+            .with_spec_id(<span class="number">1</span>)
+            .add_unbound_field(UnboundPartitionField {
+                source_id: <span class="number">1</span>,
+                field_id: <span class="prelude-val">None</span>,
+                name: <span class="string">"id_bucket"</span>.to_string(),
+                transform: Transform::Bucket(<span class="number">16</span>),
+            })
+            .unwrap()
+            .add_unbound_field(UnboundPartitionField {
+                source_id: <span class="number">2</span>,
+                field_id: <span class="prelude-val">None</span>,
+                name: <span class="string">"name"</span>.to_string(),
+                transform: Transform::Identity,
+            })
+            .unwrap()
+            .build()
+            .unwrap();
+
+        <span class="kw">let </span>partition_spec_2 = PartitionSpec::builder(<span class="kw-2">&amp;</span>schema)
+            .with_spec_id(<span class="number">1</span>)
+            .add_unbound_field(UnboundPartitionField {
+                source_id: <span class="number">2</span>,
+                field_id: <span class="prelude-val">None</span>,
+                name: <span class="string">"name"</span>.to_string(),
+                transform: Transform::Identity,
+            })
+            .unwrap()
+            .add_unbound_field(UnboundPartitionField {
+                source_id: <span class="number">1</span>,
+                field_id: <span class="prelude-val">None</span>,
+                name: <span class="string">"id_bucket"</span>.to_string(),
+                transform: Transform::Bucket(<span class="number">16</span>),
+            })
+            .unwrap()
+            .build()
+            .unwrap();
+
+        <span class="macro">assert!</span>(!partition_spec_1.is_compatible_with(<span class="kw-2">&amp;</span>partition_spec_2.into_unbound()));
+    }
+
+    <span class="attr">#[test]
+    </span><span class="kw">fn </span>test_highest_field_id_unpartitioned() {
+        <span class="kw">let </span>spec = PartitionSpec::builder(<span class="kw-2">&amp;</span>Schema::builder().with_fields(<span class="macro">vec!</span>[]).build().unwrap())
+            .with_spec_id(<span class="number">1</span>)
+            .build()
+            .unwrap();
+
+        <span class="macro">assert_eq!</span>(UNPARTITIONED_LAST_ASSIGNED_ID, spec.highest_field_id());
+    }
+
+    <span class="attr">#[test]
+    </span><span class="kw">fn </span>test_highest_field_id() {
+        <span class="kw">let </span>schema = Schema::builder()
+            .with_fields(<span class="macro">vec!</span>[
+                NestedField::required(<span class="number">1</span>, <span class="string">"id"</span>, Type::Primitive(<span class="kw">crate</span>::spec::PrimitiveType::Int))
+                    .into(),
+                NestedField::required(
+                    <span class="number">2</span>,
+                    <span class="string">"name"</span>,
+                    Type::Primitive(<span class="kw">crate</span>::spec::PrimitiveType::String),
+                )
+                .into(),
+            ])
+            .build()
+            .unwrap();
+
+        <span class="kw">let </span>spec = PartitionSpec::builder(<span class="kw-2">&amp;</span>schema)
+            .with_spec_id(<span class="number">1</span>)
+            .add_unbound_field(UnboundPartitionField {
+                source_id: <span class="number">1</span>,
+                field_id: <span class="prelude-val">Some</span>(<span class="number">1001</span>),
+                name: <span class="string">"id"</span>.to_string(),
+                transform: Transform::Identity,
+            })
+            .unwrap()
+            .add_unbound_field(UnboundPartitionField {
+                source_id: <span class="number">2</span>,
+                field_id: <span class="prelude-val">Some</span>(<span class="number">1000</span>),
+                name: <span class="string">"name"</span>.to_string(),
+                transform: Transform::Identity,
+            })
+            .unwrap()
+            .build()
+            .unwrap();
+
+        <span class="macro">assert_eq!</span>(<span class="number">1001</span>, spec.highest_field_id());
+    }
+
+    <span class="attr">#[test]
+    </span><span class="kw">fn </span>test_has_sequential_ids() {
+        <span class="kw">let </span>schema = Schema::builder()
+            .with_fields(<span class="macro">vec!</span>[
+                NestedField::required(<span class="number">1</span>, <span class="string">"id"</span>, Type::Primitive(<span class="kw">crate</span>::spec::PrimitiveType::Int))
+                    .into(),
+                NestedField::required(
+                    <span class="number">2</span>,
+                    <span class="string">"name"</span>,
+                    Type::Primitive(<span class="kw">crate</span>::spec::PrimitiveType::String),
+                )
+                .into(),
+            ])
+            .build()
+            .unwrap();
+
+        <span class="kw">let </span>spec = PartitionSpec::builder(<span class="kw-2">&amp;</span>schema)
+            .with_spec_id(<span class="number">1</span>)
+            .add_unbound_field(UnboundPartitionField {
+                source_id: <span class="number">1</span>,
+                field_id: <span class="prelude-val">Some</span>(<span class="number">1000</span>),
+                name: <span class="string">"id"</span>.to_string(),
+                transform: Transform::Identity,
+            })
+            .unwrap()
+            .add_unbound_field(UnboundPartitionField {
+                source_id: <span class="number">2</span>,
+                field_id: <span class="prelude-val">Some</span>(<span class="number">1001</span>),
+                name: <span class="string">"name"</span>.to_string(),
+                transform: Transform::Identity,
+            })
+            .unwrap()
+            .build()
+            .unwrap();
+
+        <span class="macro">assert_eq!</span>(<span class="number">1000</span>, spec.fields[<span class="number">0</span>].field_id);
+        <span class="macro">assert_eq!</span>(<span class="number">1001</span>, spec.fields[<span class="number">1</span>].field_id);
+        <span class="macro">assert!</span>(spec.has_sequential_ids());
+    }
+
+    <span class="attr">#[test]
+    </span><span class="kw">fn </span>test_sequential_ids_must_start_at_1000() {
+        <span class="kw">let </span>schema = Schema::builder()
+            .with_fields(<span class="macro">vec!</span>[
+                NestedField::required(<span class="number">1</span>, <span class="string">"id"</span>, Type::Primitive(<span class="kw">crate</span>::spec::PrimitiveType::Int))
+                    .into(),
+                NestedField::required(
+                    <span class="number">2</span>,
+                    <span class="string">"name"</span>,
+                    Type::Primitive(<span class="kw">crate</span>::spec::PrimitiveType::String),
+                )
+                .into(),
+            ])
+            .build()
+            .unwrap();
+
+        <span class="kw">let </span>spec = PartitionSpec::builder(<span class="kw-2">&amp;</span>schema)
+            .with_spec_id(<span class="number">1</span>)
+            .add_unbound_field(UnboundPartitionField {
+                source_id: <span class="number">1</span>,
+                field_id: <span class="prelude-val">Some</span>(<span class="number">999</span>),
+                name: <span class="string">"id"</span>.to_string(),
+                transform: Transform::Identity,
+            })
+            .unwrap()
+            .add_unbound_field(UnboundPartitionField {
+                source_id: <span class="number">2</span>,
+                field_id: <span class="prelude-val">Some</span>(<span class="number">1000</span>),
+                name: <span class="string">"name"</span>.to_string(),
+                transform: Transform::Identity,
+            })
+            .unwrap()
+            .build()
+            .unwrap();
+
+        <span class="macro">assert_eq!</span>(<span class="number">999</span>, spec.fields[<span class="number">0</span>].field_id);
+        <span class="macro">assert_eq!</span>(<span class="number">1000</span>, spec.fields[<span class="number">1</span>].field_id);
+        <span class="macro">assert!</span>(!spec.has_sequential_ids());
+    }
+
+    <span class="attr">#[test]
+    </span><span class="kw">fn </span>test_sequential_ids_must_have_no_gaps() {
+        <span class="kw">let </span>schema = Schema::builder()
+            .with_fields(<span class="macro">vec!</span>[
+                NestedField::required(<span class="number">1</span>, <span class="string">"id"</span>, Type::Primitive(<span class="kw">crate</span>::spec::PrimitiveType::Int))
+                    .into(),
+                NestedField::required(
+                    <span class="number">2</span>,
+                    <span class="string">"name"</span>,
+                    Type::Primitive(<span class="kw">crate</span>::spec::PrimitiveType::String),
+                )
+                .into(),
+            ])
+            .build()
+            .unwrap();
+
+        <span class="kw">let </span>spec = PartitionSpec::builder(<span class="kw-2">&amp;</span>schema)
+            .with_spec_id(<span class="number">1</span>)
+            .add_unbound_field(UnboundPartitionField {
+                source_id: <span class="number">1</span>,
+                field_id: <span class="prelude-val">Some</span>(<span class="number">1000</span>),
+                name: <span class="string">"id"</span>.to_string(),
+                transform: Transform::Identity,
+            })
+            .unwrap()
+            .add_unbound_field(UnboundPartitionField {
+                source_id: <span class="number">2</span>,
+                field_id: <span class="prelude-val">Some</span>(<span class="number">1002</span>),
+                name: <span class="string">"name"</span>.to_string(),
+                transform: Transform::Identity,
+            })
+            .unwrap()
+            .build()
+            .unwrap();
+
+        <span class="macro">assert_eq!</span>(<span class="number">1000</span>, spec.fields[<span class="number">0</span>].field_id);
+        <span class="macro">assert_eq!</span>(<span class="number">1002</span>, spec.fields[<span class="number">1</span>].field_id);
+        <span class="macro">assert!</span>(!spec.has_sequential_ids());
+    }
 }
 </code></pre></div></section></main></body></html>
\ No newline at end of file