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 <[email protected]>
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

Reply via email to