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 fe78d4d6 deploy: 026b436ff457b05da1fa05ea60e69260f62bb90c
fe78d4d6 is described below
commit fe78d4d6a7faa4db1cc4d6111fb2adfb2470664e
Author: Xuanwo <[email protected]>
AuthorDate: Sat Oct 12 05:58:46 2024 +0000
deploy: 026b436ff457b05da1fa05ea60e69260f62bb90c
---
api/iceberg/expr/enum.BoundPredicate.html | 10 +-
api/iceberg/expr/enum.Predicate.html | 22 +-
api/iceberg/expr/struct.BinaryExpression.html | 24 +-
api/iceberg/expr/struct.SetExpression.html | 14 +-
api/iceberg/expr/struct.UnaryExpression.html | 9 +-
api/iceberg/expr/trait.Bind.html | 2 +-
.../struct.IcebergTableProvider.html | 4 +-
api/search-index.js | 2 +-
api/search.desc/iceberg/iceberg-desc-0-.js | 2 +-
api/src/iceberg/expr/predicate.rs.html | 50 +-
.../physical_plan/expr_to_predicate.rs.html | 514 +++++++++++++--------
.../iceberg_datafusion/physical_plan/scan.rs.html | 40 +-
api/src/iceberg_datafusion/table.rs.html | 20 +-
13 files changed, 426 insertions(+), 287 deletions(-)
diff --git a/api/iceberg/expr/enum.BoundPredicate.html
b/api/iceberg/expr/enum.BoundPredicate.html
index 2c7416cd..793df9c4 100644
--- a/api/iceberg/expr/enum.BoundPredicate.html
+++ b/api/iceberg/expr/enum.BoundPredicate.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="Bound
predicate expression after binding to a schema."><title>BoundPredicate in
iceberg::expr -
Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,FiraSans-Regular-018c141bf0843ffd.woff2,
[...]
+<!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="Bound
predicate expression after binding to a schema."><title>BoundPredicate in
iceberg::expr -
Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,FiraSans-Regular-018c141bf0843ffd.woff2,
[...]
AlwaysTrue,
AlwaysFalse,
And(<a class="struct" href="struct.LogicalExpression.html" title="struct
iceberg::expr::LogicalExpression">LogicalExpression</a><<a class="enum"
href="enum.BoundPredicate.html" title="enum
iceberg::expr::BoundPredicate">BoundPredicate</a>, 2>),
@@ -16,11 +16,11 @@
</div><section id="variant.Unary" class="variant"><a href="#variant.Unary"
class="anchor">§</a><h3 class="code-header">Unary(<a class="struct"
href="struct.UnaryExpression.html" title="struct
iceberg::expr::UnaryExpression">UnaryExpression</a><<a class="struct"
href="struct.BoundReference.html" title="struct
iceberg::expr::BoundReference">BoundReference</a>>)</h3></section><div
class="docblock"><p>Unary expression, for example, <code>a IS NULL</code>.</p>
</div><section id="variant.Binary" class="variant"><a href="#variant.Binary"
class="anchor">§</a><h3 class="code-header">Binary(<a class="struct"
href="struct.BinaryExpression.html" title="struct
iceberg::expr::BinaryExpression">BinaryExpression</a><<a class="struct"
href="struct.BoundReference.html" title="struct
iceberg::expr::BoundReference">BoundReference</a>>)</h3></section><div
class="docblock"><p>Binary expression, for example, <code>a > 10</code>.</p>
</div><section id="variant.Set" class="variant"><a href="#variant.Set"
class="anchor">§</a><h3 class="code-header">Set(<a class="struct"
href="struct.SetExpression.html" title="struct
iceberg::expr::SetExpression">SetExpression</a><<a class="struct"
href="struct.BoundReference.html" title="struct
iceberg::expr::BoundReference">BoundReference</a>>)</h3></section><div
class="docblock"><p>Set predicates, for example, <code>a IN (1, 2,
3)</code>.</p>
-</div></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-BoundPredicate" class="impl"><a
class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#653">source</a><a
href="#impl-Clone-for-BoundPredicate" class="anchor">§</a><h3
class="code-header">impl <a class="trait" h [...]
- __D: <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserializer.html"
title="trait
serde::de::Deserializer">Deserializer</a><'de>,</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-Displ [...]
+</div></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-BoundPredicate" class="impl"><a
class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#676">source</a><a
href="#impl-Clone-for-BoundPredicate" class="anchor">§</a><h3
class="code-header">impl <a class="trait" h [...]
+ __D: <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserializer.html"
title="trait
serde::de::Deserializer">Deserializer</a><'de>,</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-Displ [...]
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-BoundPredicate" class="impl"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#653">source</a><a
href="#impl-Serialize-for-BoundPredicate" 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="tr
[...]
- __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-StructuralPartialEq-for-BoundPredicate" class="impl"><a class="src
rightside" href=". [...]
+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-BoundPredicate" class="impl"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#676">source</a><a
href="#impl-Serialize-for-BoundPredicate" 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="tr
[...]
+ __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-StructuralPartialEq-for-BoundPredicate" class="impl"><a class="src
rightside" href=". [...]
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/expr/enum.Predicate.html
b/api/iceberg/expr/enum.Predicate.html
index 95ba266c..a2b14a0e 100644
--- a/api/iceberg/expr/enum.Predicate.html
+++ b/api/iceberg/expr/enum.Predicate.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
predicate expression before binding to a schema."><title>Predicate in
iceberg::expr -
Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,FiraSans-Regular-018c141bf0843ffd.woff2,Fi
[...]
+<!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
predicate expression before binding to a schema."><title>Predicate in
iceberg::expr -
Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,FiraSans-Regular-018c141bf0843ffd.woff2,Fi
[...]
AlwaysTrue,
AlwaysFalse,
And(<a class="struct" href="struct.LogicalExpression.html" title="struct
iceberg::expr::LogicalExpression">LogicalExpression</a><<a class="enum"
href="enum.Predicate.html" title="enum iceberg::expr::Predicate">Predicate</a>,
2>),
@@ -16,7 +16,7 @@
</div><section id="variant.Unary" class="variant"><a href="#variant.Unary"
class="anchor">§</a><h3 class="code-header">Unary(<a class="struct"
href="struct.UnaryExpression.html" title="struct
iceberg::expr::UnaryExpression">UnaryExpression</a><<a class="struct"
href="struct.Reference.html" title="struct
iceberg::expr::Reference">Reference</a>>)</h3></section><div
class="docblock"><p>Unary expression, for example, <code>a IS NULL</code>.</p>
</div><section id="variant.Binary" class="variant"><a href="#variant.Binary"
class="anchor">§</a><h3 class="code-header">Binary(<a class="struct"
href="struct.BinaryExpression.html" title="struct
iceberg::expr::BinaryExpression">BinaryExpression</a><<a class="struct"
href="struct.Reference.html" title="struct
iceberg::expr::Reference">Reference</a>>)</h3></section><div
class="docblock"><p>Binary expression, for example, <code>a > 10</code>.</p>
</div><section id="variant.Set" class="variant"><a href="#variant.Set"
class="anchor">§</a><h3 class="code-header">Set(<a class="struct"
href="struct.SetExpression.html" title="struct
iceberg::expr::SetExpression">SetExpression</a><<a class="struct"
href="struct.Reference.html" title="struct
iceberg::expr::Reference">Reference</a>>)</h3></section><div
class="docblock"><p>Set predicates, for example, <code>a in (1, 2,
3)</code>.</p>
-</div></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-Predicate" class="impl"><a class="src
rightside" href="../../src/iceberg/expr/predicate.rs.html#470-623">source</a><a
href="#impl-Predicate" class="anchor">§</a><h3 class="code-header">impl <a
class="enum" href="enum.Predicate.html" title="enum iceberg::expr [...]
+</div></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-Predicate" class="impl"><a class="src
rightside" href="../../src/iceberg/expr/predicate.rs.html#493-646">source</a><a
href="#impl-Predicate" class="anchor">§</a><h3 class="code-header">impl <a
class="enum" href="enum.Predicate.html" title="enum iceberg::expr [...]
<h5 id="example"><a class="doc-anchor" href="#example">§</a>Example</h5>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span
class="kw">use </span>std::ops::Bound::Unbounded;
@@ -30,7 +30,7 @@
<span class="kw">let </span>expr = expr1.and(expr2);
<span class="macro">assert_eq!</span>(<span class="kw-2">&</span><span
class="macro">format!</span>(<span class="string">"{expr}"</span>), <span
class="string">"(a < 10) AND (b < 20)"</span>);</code></pre></div>
-</div></details><details class="toggle method-toggle" open><summary><section
id="method.or" class="method"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#517-525">source</a><h4
class="code-header">pub fn <a href="#method.or" class="fn">or</a>(self, other:
<a class="enum" href="enum.Predicate.html" title="enum
iceberg::expr::Predicate">Predicate</a>) -> <a class="enum"
href="enum.Predicate.html" title="enum
iceberg::expr::Predicate">Predicate</a></h4></section> [...]
+</div></details><details class="toggle method-toggle" open><summary><section
id="method.or" class="method"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#540-548">source</a><h4
class="code-header">pub fn <a href="#method.or" class="fn">or</a>(self, other:
<a class="enum" href="enum.Predicate.html" title="enum
iceberg::expr::Predicate">Predicate</a>) -> <a class="enum"
href="enum.Predicate.html" title="enum
iceberg::expr::Predicate">Predicate</a></h4></section> [...]
<h5 id="example-1"><a class="doc-anchor" href="#example-1">§</a>Example</h5>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span
class="kw">use </span>std::ops::Bound::Unbounded;
@@ -44,7 +44,7 @@
<span class="kw">let </span>expr = expr1.or(expr2);
<span class="macro">assert_eq!</span>(<span class="kw-2">&</span><span
class="macro">format!</span>(<span class="string">"{expr}"</span>), <span
class="string">"(a < 10) OR (b < 20)"</span>);</code></pre></div>
-</div></details><details class="toggle method-toggle" open><summary><section
id="method.negate" class="method"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#550-578">source</a><h4
class="code-header">pub fn <a href="#method.negate" class="fn">negate</a>(self)
-> <a class="enum" href="enum.Predicate.html" title="enum
iceberg::expr::Predicate">Predicate</a></h4></section></summary><div
class="docblock"><p>Returns a predicate representing the negation (‘NOT’) of
[...]
+</div></details><details class="toggle method-toggle" open><summary><section
id="method.negate" class="method"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#573-601">source</a><h4
class="code-header">pub fn <a href="#method.negate" class="fn">negate</a>(self)
-> <a class="enum" href="enum.Predicate.html" title="enum
iceberg::expr::Predicate">Predicate</a></h4></section></summary><div
class="docblock"><p>Returns a predicate representing the negation (‘NOT’) of
[...]
by using inverse predicates rather than wrapping in a <code>NOT</code>.
Used for <code>NOT</code> elimination.</p>
<h5 id="example-2"><a class="doc-anchor" href="#example-2">§</a>Example</h5>
@@ -63,7 +63,7 @@ Used for <code>NOT</code> elimination.</p>
<span class="kw">let </span>result = expr2.negate();
<span class="macro">assert_eq!</span>(<span class="kw-2">&</span><span
class="macro">format!</span>(<span class="string">"{result}"</span>), <span
class="string">"(b >= 5) OR (c >= 10)"</span>);</code></pre></div>
-</div></details><details class="toggle method-toggle" open><summary><section
id="method.rewrite_not" class="method"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#598-622">source</a><h4
class="code-header">pub fn <a href="#method.rewrite_not"
class="fn">rewrite_not</a>(self) -> <a class="enum"
href="enum.Predicate.html" title="enum
iceberg::expr::Predicate">Predicate</a></h4></section></summary><div
class="docblock"><p>Simplifies the expression by removing <co [...]
+</div></details><details class="toggle method-toggle" open><summary><section
id="method.rewrite_not" class="method"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#621-645">source</a><h4
class="code-header">pub fn <a href="#method.rewrite_not"
class="fn">rewrite_not</a>(self) -> <a class="enum"
href="enum.Predicate.html" title="enum
iceberg::expr::Predicate">Predicate</a></h4></section></summary><div
class="docblock"><p>Simplifies the expression by removing <co [...]
directly negating the inner expressions instead. The transformation
applies logical laws (such as De Morgan’s laws) to
recursively negate and simplify inner expressions within <code>NOT</code>
@@ -78,12 +78,12 @@ predicates.</p>
<span class="kw">let </span>result = expression.rewrite_not();
<span class="macro">assert_eq!</span>(<span class="kw-2">&</span><span
class="macro">format!</span>(<span class="string">"{result}"</span>), <span
class="string">"a >= 5"</span>);</code></pre></div>
-</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-Bind-for-Predicate" class="impl"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#297-437">source</a><a
href="#impl-Bind-for-Predicate" class="anchor">§</a><h3
class="code-header">impl [...]
+</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-Bind-for-Predicate" class="impl"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#320-460">source</a><a
href="#impl-Bind-for-Predicate" class="anchor">§</a><h3
class="code-header">impl [...]
&self,
schema: <a class="type" href="../spec/type.SchemaRef.html" title="type
iceberg::spec::SchemaRef">SchemaRef</a>,
case_sensitive: <a class="primitive"
href="https://doc.rust-lang.org/nightly/std/primitive.bool.html">bool</a>,
-) -> <a class="type" href="../type.Result.html" title="type
iceberg::Result">Result</a><<a class="enum" href="enum.BoundPredicate.html"
title="enum
iceberg::expr::BoundPredicate">BoundPredicate</a>></h4></section></summary><div
class='docblock'>Bind an expression to a
schema.</div></details></div></details><details class="toggle
implementors-toggle" open><summary><section id="impl-Clone-for-Predicate"
class="impl"><a class="src rightside" href="../../src/iceberg/expr/predicate.r
[...]
- __D: <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserializer.html"
title="trait
serde::de::Deserializer">Deserializer</a><'de>,</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-Displ [...]
+) -> <a class="type" href="../type.Result.html" title="type
iceberg::Result">Result</a><<a class="enum" href="enum.BoundPredicate.html"
title="enum
iceberg::expr::BoundPredicate">BoundPredicate</a>></h4></section></summary><div
class='docblock'>Bind an expression to a
schema.</div></details></div></details><details class="toggle
implementors-toggle" open><summary><section id="impl-Clone-for-Predicate"
class="impl"><a class="src rightside" href="../../src/iceberg/expr/predicate.r
[...]
+ __D: <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserializer.html"
title="trait
serde::de::Deserializer">Deserializer</a><'de>,</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-Displ [...]
<p>This is different from <a href="enum.Predicate.html#method.negate"
title="method
iceberg::expr::Predicate::negate"><code>Predicate::negate()</code></a> since it
doesn’t rewrite expression, but
just adds a <code>NOT</code> operator.</p>
<h5 id="example-4"><a class="doc-anchor" href="#example-4">§</a>Example</h5>
@@ -97,10 +97,10 @@ just adds a <code>NOT</code> operator.</p>
<span class="kw">let </span>expr = !expr1;
<span class="macro">assert_eq!</span>(<span class="kw-2">&</span><span
class="macro">format!</span>(<span class="string">"{expr}"</span>), <span
class="string">"NOT (a < 10)"</span>);</code></pre></div>
-</div></details><details class="toggle" open><summary><section
id="associatedtype.Output" class="associatedtype trait-impl"><a
href="#associatedtype.Output" class="anchor">§</a><h4 class="code-header">type
<a
href="https://doc.rust-lang.org/nightly/core/ops/bit/trait.Not.html#associatedtype.Output"
class="associatedtype">Output</a> = <a class="enum" href="enum.Predicate.html"
title="enum
iceberg::expr::Predicate">Predicate</a></h4></section></summary><div
class='docblock'>The resulting t [...]
+</div></details><details class="toggle" open><summary><section
id="associatedtype.Output" class="associatedtype trait-impl"><a
href="#associatedtype.Output" class="anchor">§</a><h4 class="code-header">type
<a
href="https://doc.rust-lang.org/nightly/core/ops/bit/trait.Not.html#associatedtype.Output"
class="associatedtype">Output</a> = <a class="enum" href="enum.Predicate.html"
title="enum
iceberg::expr::Predicate">Predicate</a></h4></section></summary><div
class='docblock'>The resulting t [...]
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-Predicate"
class="impl"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#277">source</a><a
href="#impl-Serialize-for-Predicate" 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 serde: [...]
- __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-StructuralPartialEq-for-Predicate" class="impl"><a class="src
rightside" href="../../ [...]
+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-Predicate"
class="impl"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#300">source</a><a
href="#impl-Serialize-for-Predicate" 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 serde: [...]
+ __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-StructuralPartialEq-for-Predicate" class="impl"><a class="src
rightside" href="../../ [...]
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/expr/struct.BinaryExpression.html
b/api/iceberg/expr/struct.BinaryExpression.html
index 790051b4..6ffe9dcc 100644
--- a/api/iceberg/expr/struct.BinaryExpression.html
+++ b/api/iceberg/expr/struct.BinaryExpression.html
@@ -1,11 +1,21 @@
-<!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="Binary
predicate, for example, `a > 10`."><title>BinaryExpression in iceberg::expr
-
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="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-Bind-for-BinaryExpression%3CT%3E"
class="impl"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#200-211">source</a><a
href="#impl-Bind-for-BinaryExpression%3CT%3E" class="anchor">§</a><h3
class="code-header" [...]
- T: <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserialize.html"
title="trait
serde::de::Deserialize">Deserialize</a><'de>,</div></h3></section></summary><div
class="impl-items"><details class="toggle method-toggle"
open><summary><section id="method.deserialize" class="method trait-impl"><a
class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#152">source</a><a
href="#method.deserialize" class="anchor">§</a><h4 class="code-header">fn <a hr
[...]
- __D: <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserializer.html"
title="trait
serde::de::Deserializer">Deserializer</a><'de>,</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-Displ [...]
+<!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="Binary
predicate, for example, `a > 10`."><title>BinaryExpression in iceberg::expr
-
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="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-BinaryExpression%3CT%3E"
class="impl"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#182-215">source</a><a
href="#impl-BinaryExpression%3CT%3E" class="anchor">§</a><h3
class="code-header">impl<T> <a class="struct" href="str [...]
+<h5 id="example"><a class="doc-anchor" href="#example">§</a>Example</h5>
+<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span
class="kw">use </span>iceberg::expr::{BinaryExpression, PredicateOperator,
Reference};
+<span class="kw">use </span>iceberg::spec::Datum;
+
+BinaryExpression::new(
+ PredicateOperator::LessThanOrEq,
+ Reference::new(<span class="string">"a"</span>),
+ Datum::int(<span class="number">10</span>),
+);</code></pre></div>
+</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-Bind-for-BinaryExpression%3CT%3E" class="impl"><a class="src
rightside" href="../../src/iceberg/expr/predicate.rs.html#223-234">source</a><a
href="#impl-Bind-for-BinaryExpression%3CT%3E" class="anchor">§</a>< [...]
+ T: <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserialize.html"
title="trait
serde::de::Deserialize">Deserialize</a><'de>,</div></h3></section></summary><div
class="impl-items"><details class="toggle method-toggle"
open><summary><section id="method.deserialize" class="method trait-impl"><a
class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#161">source</a><a
href="#method.deserialize" class="anchor">§</a><h4 class="code-header">fn <a hr
[...]
+ __D: <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserializer.html"
title="trait
serde::de::Deserializer">Deserializer</a><'de>,</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-Displ [...]
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-BinaryExpression%3CT%3E" class="impl"><a class="src
rightside" href="../../src/iceberg/expr/predicate.rs.html#152">source</a><a
href="#impl-Serialize-for-BinaryExpression%3CT%3E" class="anchor">§</a><h3
class="code-header">impl<T> <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/ser/trai [...]
- T: <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serialize.html"
title="trait
serde::ser::Serialize">Serialize</a>,</div></h3></section></summary><div
class="impl-items"><details class="toggle method-toggle" open><summary><section
id="method.serialize" class="method trait-impl"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#152">source</a><a
href="#method.serialize" class="anchor">§</a><h4 class="code-header">fn <a
href="https://docs.rs [...]
- __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-StructuralPartialEq-for-BinaryExpression%3CT%3E" class="impl"><a
class="src rightside [...]
+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-BinaryExpression%3CT%3E" class="impl"><a class="src
rightside" href="../../src/iceberg/expr/predicate.rs.html#161">source</a><a
href="#impl-Serialize-for-BinaryExpression%3CT%3E" class="anchor">§</a><h3
class="code-header">impl<T> <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/ser/trai [...]
+ T: <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serialize.html"
title="trait
serde::ser::Serialize">Serialize</a>,</div></h3></section></summary><div
class="impl-items"><details class="toggle method-toggle" open><summary><section
id="method.serialize" class="method trait-impl"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#161">source</a><a
href="#method.serialize" class="anchor">§</a><h4 class="code-header">fn <a
href="https://docs.rs [...]
+ __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-StructuralPartialEq-for-BinaryExpression%3CT%3E" class="impl"><a
class="src rightside [...]
T: <a class="trait"
href="https://doc.rust-lang.org/nightly/core/marker/trait.Freeze.html"
title="trait core::marker::Freeze">Freeze</a>,</div></h3></section><section
id="impl-RefUnwindSafe-for-BinaryExpression%3CT%3E" class="impl"><a
href="#impl-RefUnwindSafe-for-BinaryExpression%3CT%3E" class="anchor">§</a><h3
class="code-header">impl<T> <a class="trait"
href="https://doc.rust-lang.org/nightly/core/panic/unwind_safe/trait.RefUnwindSafe.html"
title="trait core::panic::unwind_s [...]
T: <a class="trait"
href="https://doc.rust-lang.org/nightly/core/panic/unwind_safe/trait.RefUnwindSafe.html"
title="trait
core::panic::unwind_safe::RefUnwindSafe">RefUnwindSafe</a>,</div></h3></section><section
id="impl-Send-for-BinaryExpression%3CT%3E" class="impl"><a
href="#impl-Send-for-BinaryExpression%3CT%3E" class="anchor">§</a><h3
class="code-header">impl<T> <a class="trait"
href="https://doc.rust-lang.org/nightly/core/marker/trait.Send.html"
title="trait core::marker::S [...]
T: <a class="trait"
href="https://doc.rust-lang.org/nightly/core/marker/trait.Send.html"
title="trait core::marker::Send">Send</a>,</div></h3></section><section
id="impl-Sync-for-BinaryExpression%3CT%3E" class="impl"><a
href="#impl-Sync-for-BinaryExpression%3CT%3E" class="anchor">§</a><h3
class="code-header">impl<T> <a class="trait"
href="https://doc.rust-lang.org/nightly/core/marker/trait.Sync.html"
title="trait core::marker::Sync">Sync</a> for <a class="struct" href="struct.B
[...]
diff --git a/api/iceberg/expr/struct.SetExpression.html
b/api/iceberg/expr/struct.SetExpression.html
index 7d6e6dd5..0b2c02bc 100644
--- a/api/iceberg/expr/struct.SetExpression.html
+++ b/api/iceberg/expr/struct.SetExpression.html
@@ -1,11 +1,11 @@
-<!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="Set
predicates, for example, `a in (1, 2, 3)`."><title>SetExpression in
iceberg::expr -
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="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-Bind-for-SetExpression%3CT%3E" class="impl"><a
class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#255-266">source</a><a
href="#impl-Bind-for-SetExpression%3CT%3E" class="anchor">§</a><h3
class="code-header">impl& [...]
- T: <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserialize.html"
title="trait
serde::de::Deserialize">Deserialize</a><'de>,</div></h3></section></summary><div
class="impl-items"><details class="toggle method-toggle"
open><summary><section id="method.deserialize" class="method trait-impl"><a
class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#214">source</a><a
href="#method.deserialize" class="anchor">§</a><h4 class="code-header">fn <a hr
[...]
- __D: <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserializer.html"
title="trait
serde::de::Deserializer">Deserializer</a><'de>,</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-Displ [...]
+<!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="Set
predicates, for example, `a in (1, 2, 3)`."><title>SetExpression in
iceberg::expr -
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="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-Bind-for-SetExpression%3CT%3E" class="impl"><a
class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#278-289">source</a><a
href="#impl-Bind-for-SetExpression%3CT%3E" class="anchor">§</a><h3
class="code-header">impl& [...]
+ T: <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserialize.html"
title="trait
serde::de::Deserialize">Deserialize</a><'de>,</div></h3></section></summary><div
class="impl-items"><details class="toggle method-toggle"
open><summary><section id="method.deserialize" class="method trait-impl"><a
class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#237">source</a><a
href="#method.deserialize" class="anchor">§</a><h4 class="code-header">fn <a hr
[...]
+ __D: <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserializer.html"
title="trait
serde::de::Deserializer">Deserializer</a><'de>,</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-Displ [...]
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-SetExpression%3CT%3E" class="impl"><a class="src
rightside" href="../../src/iceberg/expr/predicate.rs.html#214">source</a><a
href="#impl-Serialize-for-SetExpression%3CT%3E" class="anchor">§</a><h3
class="code-header">impl<T> <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/ser/trait.Seri [...]
- T: <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serialize.html"
title="trait
serde::ser::Serialize">Serialize</a>,</div></h3></section></summary><div
class="impl-items"><details class="toggle method-toggle" open><summary><section
id="method.serialize" class="method trait-impl"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#214">source</a><a
href="#method.serialize" class="anchor">§</a><h4 class="code-header">fn <a
href="https://docs.rs [...]
- __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-StructuralPartialEq-for-SetExpression%3CT%3E" class="impl"><a
class="src rightside" h [...]
+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-SetExpression%3CT%3E" class="impl"><a class="src
rightside" href="../../src/iceberg/expr/predicate.rs.html#237">source</a><a
href="#impl-Serialize-for-SetExpression%3CT%3E" class="anchor">§</a><h3
class="code-header">impl<T> <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/ser/trait.Seri [...]
+ T: <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/ser/trait.Serialize.html"
title="trait
serde::ser::Serialize">Serialize</a>,</div></h3></section></summary><div
class="impl-items"><details class="toggle method-toggle" open><summary><section
id="method.serialize" class="method trait-impl"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#237">source</a><a
href="#method.serialize" class="anchor">§</a><h4 class="code-header">fn <a
href="https://docs.rs [...]
+ __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-StructuralPartialEq-for-SetExpression%3CT%3E" class="impl"><a
class="src rightside" h [...]
T: <a class="trait"
href="https://doc.rust-lang.org/nightly/core/marker/trait.Freeze.html"
title="trait core::marker::Freeze">Freeze</a>,</div></h3></section><section
id="impl-RefUnwindSafe-for-SetExpression%3CT%3E" class="impl"><a
href="#impl-RefUnwindSafe-for-SetExpression%3CT%3E" class="anchor">§</a><h3
class="code-header">impl<T> <a class="trait"
href="https://doc.rust-lang.org/nightly/core/panic/unwind_safe/trait.RefUnwindSafe.html"
title="trait core::panic::unwind_safe::R [...]
T: <a class="trait"
href="https://doc.rust-lang.org/nightly/core/panic/unwind_safe/trait.RefUnwindSafe.html"
title="trait
core::panic::unwind_safe::RefUnwindSafe">RefUnwindSafe</a>,</div></h3></section><section
id="impl-Send-for-SetExpression%3CT%3E" class="impl"><a
href="#impl-Send-for-SetExpression%3CT%3E" class="anchor">§</a><h3
class="code-header">impl<T> <a class="trait"
href="https://doc.rust-lang.org/nightly/core/marker/trait.Send.html"
title="trait core::marker::Send">S [...]
T: <a class="trait"
href="https://doc.rust-lang.org/nightly/core/marker/trait.Send.html"
title="trait core::marker::Send">Send</a>,</div></h3></section><section
id="impl-Sync-for-SetExpression%3CT%3E" class="impl"><a
href="#impl-Sync-for-SetExpression%3CT%3E" class="anchor">§</a><h3
class="code-header">impl<T> <a class="trait"
href="https://doc.rust-lang.org/nightly/core/marker/trait.Sync.html"
title="trait core::marker::Sync">Sync</a> for <a class="struct"
href="struct.SetExpr [...]
diff --git a/api/iceberg/expr/struct.UnaryExpression.html
b/api/iceberg/expr/struct.UnaryExpression.html
index e9faf0f7..930c31c7 100644
--- a/api/iceberg/expr/struct.UnaryExpression.html
+++ b/api/iceberg/expr/struct.UnaryExpression.html
@@ -1,5 +1,10 @@
-<!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="Unary
predicate, for example, `a IS NULL`."><title>UnaryExpression in iceberg::expr -
Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,FiraSans-Regular-018c141bf0843ffd.woff2,FiraSans-M
[...]
-</div></details><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-Bind-for-UnaryExpression%3CT%3E"
class="impl"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#125-132">source</a><a
href="#impl-Bind-for-UnaryExpression%3CT%3E" class="anchor">§</a><h3
class="code-header">i [...]
+<!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="Unary
predicate, for example, `a IS NULL`."><title>UnaryExpression in iceberg::expr -
Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,FiraSans-Regular-018c141bf0843ffd.woff2,FiraSans-M
[...]
+</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-UnaryExpression%3CT%3E"
class="impl"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#134-158">source</a><a
href="#impl-UnaryExpression%3CT%3E" class="anchor">§</a><h3
class="code-header">impl<T> <a class="struct" href="struc [...]
+<h5 id="example"><a class="doc-anchor" href="#example">§</a>Example</h5>
+<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span
class="kw">use </span>iceberg::expr::{PredicateOperator, Reference,
UnaryExpression};
+
+UnaryExpression::new(PredicateOperator::IsNull, Reference::new(<span
class="string">"c"</span>));</code></pre></div>
+</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-Bind-for-UnaryExpression%3CT%3E" class="impl"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#125-132">source</a><a
href="#impl-Bind-for-UnaryExpression%3CT%3E" class="anchor">§</a><h3 [...]
T: <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserialize.html"
title="trait
serde::de::Deserialize">Deserialize</a><'de>,</div></h3></section></summary><div
class="impl-items"><details class="toggle method-toggle"
open><summary><section id="method.deserialize" class="method trait-impl"><a
class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#101">source</a><a
href="#method.deserialize" class="anchor">§</a><h4 class="code-header">fn <a hr
[...]
__D: <a class="trait"
href="https://docs.rs/serde/1.0.210/serde/de/trait.Deserializer.html"
title="trait
serde::de::Deserializer">Deserializer</a><'de>,</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-Displ [...]
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= [...]
diff --git a/api/iceberg/expr/trait.Bind.html b/api/iceberg/expr/trait.Bind.html
index 5b26a939..52de8ba2 100644
--- a/api/iceberg/expr/trait.Bind.html
+++ b/api/iceberg/expr/trait.Bind.html
@@ -10,5 +10,5 @@
}</code></pre><details class="toggle top-doc" open><summary
class="hideme"><span>Expand description</span></summary><div
class="docblock"><p>Bind expression to a schema.</p>
</div></details><h2 id="required-associated-types"
class="section-header">Required Associated Types<a
href="#required-associated-types" class="anchor">§</a></h2><div
class="methods"><details class="toggle" open><summary><section
id="associatedtype.Bound" class="method"><a class="src rightside"
href="../../src/iceberg/expr/mod.rs.html#158">source</a><h4
class="code-header">type <a href="#associatedtype.Bound"
class="associatedtype">Bound</a></h4></section></summary><div
class="docblock">< [...]
</div></details></div><h2 id="required-methods"
class="section-header">Required Methods<a href="#required-methods"
class="anchor">§</a></h2><div class="methods"><details class="toggle
method-toggle" open><summary><section id="tymethod.bind" class="method"><a
class="src rightside"
href="../../src/iceberg/expr/mod.rs.html#160">source</a><h4
class="code-header">fn <a href="#tymethod.bind" class="fn">bind</a>(&self,
schema: <a class="type" href="../spec/type.SchemaRef.html" title="type i [...]
-</div></details></div><h2 id="implementors"
class="section-header">Implementors<a href="#implementors"
class="anchor">§</a></h2><div id="implementors-list"><details class="toggle
implementors-toggle"><summary><section id="impl-Bind-for-Predicate"
class="impl"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#297-437">source</a><a
href="#impl-Bind-for-Predicate" class="anchor">§</a><h3
class="code-header">impl <a class="trait" href="trait.Bind.html" title="trait
iceb [...]
+</div></details></div><h2 id="implementors"
class="section-header">Implementors<a href="#implementors"
class="anchor">§</a></h2><div id="implementors-list"><details class="toggle
implementors-toggle"><summary><section id="impl-Bind-for-Predicate"
class="impl"><a class="src rightside"
href="../../src/iceberg/expr/predicate.rs.html#320-460">source</a><a
href="#impl-Bind-for-Predicate" class="anchor">§</a><h3
class="code-header">impl <a class="trait" href="trait.Bind.html" title="trait
iceb [...]
T::<a class="associatedtype" href="trait.Bind.html#associatedtype.Bound"
title="type iceberg::expr::Bind::Bound">Bound</a>: <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"><section id="associatedtype.Bound-6" class="associatedtype
trait-impl"><a href="#associatedtype.Bound-6" class="anchor">§</a><h4
class="code-header">type <a href="#associatedtype [...]
\ No newline at end of file
diff --git a/api/iceberg_datafusion/struct.IcebergTableProvider.html
b/api/iceberg_datafusion/struct.IcebergTableProvider.html
index 3f4e2ecb..3a2872ff 100644
--- a/api/iceberg_datafusion/struct.IcebergTableProvider.html
+++ b/api/iceberg_datafusion/struct.IcebergTableProvider.html
@@ -2,7 +2,7 @@
managing access to a <a href="../iceberg/table/struct.Table.html"
title="struct iceberg::table::Table"><code>Table</code></a>.</p>
</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-IcebergTableProvider"
class="impl"><a class="src rightside"
href="../src/iceberg_datafusion/table.rs.html#43-66">source</a><a
href="#impl-IcebergTableProvider" class="anchor">§</a><h3
class="code-header">impl <a class="struct" href="struct.IcebergTablePr [...]
using the given table. Can be used to create a table provider from an existing
table regardless of the catalog implementation.</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-TableProvider-for-IcebergTableProvider" class="impl"><a class="src
rightside" href="../src/iceberg_datafusion/table.rs.html#69-112">source</a><a
href="#impl-TableProvider-for-IcebergTableProvider" class="anch [...]
+</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-TableProvider-for-IcebergTableProvider" class="impl"><a class="src
rightside" href="../src/iceberg_datafusion/table.rs.html#69-105">source</a><a
href="#impl-TableProvider-for-IcebergTableProvider" class="anch [...]
downcast to a specific implementation.</div></details><details class="toggle
method-toggle" open><summary><section id="method.schema" class="method
trait-impl"><a class="src rightside"
href="../src/iceberg_datafusion/table.rs.html#74-76">source</a><a
href="#method.schema" class="anchor">§</a><h4 class="code-header">fn <a
class="fn">schema</a>(&self) ->
ArrowSchemaRef</h4></section></summary><div class='docblock'>Get a reference to
the schema for this table</div></details><details [...]
&'life0 self,
_state: &'life1 dyn Session,
@@ -15,7 +15,7 @@ downcast to a specific
implementation.</div></details><details class="toggle met
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,</div></h4></section></summary><div
class='docblock'>Create an [<code>ExecutionPlan</code>] for scanning the table
with optionally
-specified <code>projection</code>, <code>filter</code> and <code>limit</code>,
described below. <a>Read more</a></div></details><details class="toggle
method-toggle" open><summary><section id="method.supports_filters_pushdown"
class="method trait-impl"><a class="src rightside"
href="../src/iceberg_datafusion/table.rs.html#97-111">source</a><a
href="#method.supports_filters_pushdown" class="anchor">§</a><h4
class="code-header">fn <a class="fn">supports_filters_pushdown</a>(
+specified <code>projection</code>, <code>filter</code> and <code>limit</code>,
described below. <a>Read more</a></div></details><details class="toggle
method-toggle" open><summary><section id="method.supports_filters_pushdown"
class="method trait-impl"><a class="src rightside"
href="../src/iceberg_datafusion/table.rs.html#97-104">source</a><a
href="#method.supports_filters_pushdown" class="anchor">§</a><h4
class="code-header">fn <a class="fn">supports_filters_pushdown</a>(
&self,
filters: &[&Expr],
) -> <a class="enum"
href="https://doc.rust-lang.org/nightly/core/result/enum.Result.html"
title="enum core::result::Result">Result</a><<a class="struct"
href="https://doc.rust-lang.org/nightly/alloc/vec/struct.Vec.html"
title="struct alloc::vec::Vec">Vec</a><TableProviderFilterPushDown>,
DataFusionError></h4></section></summary><div class='docblock'>Specify if
DataFusion should provide filter expressions to the
diff --git a/api/search-index.js b/api/search-index.js
index 16fd7b9f..6f5076c6 100644
--- a/api/search-index.js
+++ b/api/search-index.js
@@ -1,5 +1,5 @@
var searchIndex = new Map(JSON.parse('[\
-["iceberg",{"t":"PPPPPKPPPPPFGPPPFFPPPPPPIPPPPPPFFFGGPPPFNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMMOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMMQNNNNNNNNNNNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNNNNNNNNNNNNNNNNNNNNNCNMMMOONNNOOONOMNNNNNNONOOMOCOONNNNONCOCMNNNNNNNNNNCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMMNNNNNNNNNNNNNCOOOOOOOOOOOOOOOOOOOOOOOOOFFKRRNNNNNNNNHHNNNNNNNNNNNNNNNNNNNNNNNNNNNMMMNMHMNNNNNNNHNNNNNNPPPPPPPPFKRGFIPPPPPPPPFPPPPPPPPPGGFPPFPIPPFNNMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
[...]
+["iceberg",{"t":"PPPPPKPPPPPFGPPPFFPPPPPPIPPPPPPFFFGGPPPFNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMMOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMMQNNNNNNNNNNNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNNNNNNNNNNNNNNNNNNNNNCNMMMOONNNOOONOMNNNNNNONOOMOCOONNNNONCOCMNNNNNNNNNNCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMMNNNNNNNNNNNNNCOOOOOOOOOOOOOOOOOOOOOOOOOFFKRRNNNNNNNNHHNNNNNNNNNNNNNNNNNNNNNNNNNNNMMMNMHMNNNNNNNHNNNNNNPPPPPPPPFKRGFIPPPPPPPPFPPPPPPPPPGGFPPFPIPPFNNMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
[...]
["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 a943702c..b7442b55 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/expr/predicate.rs.html
b/api/src/iceberg/expr/predicate.rs.html
index 1667903d..4aacc8d6 100644
--- a/api/src/iceberg/expr/predicate.rs.html
+++ b/api/src/iceberg/expr/predicate.rs.html
@@ -1285,6 +1285,29 @@
<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>
</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
@@ -1419,7 +1442,16 @@
}
<span class="kw">impl</span><T> UnaryExpression<T> {
- <span class="kw">pub</span>(<span class="kw">crate</span>) <span
class="kw">fn </span>new(op: PredicateOperator, term: T) -> <span
class="self">Self </span>{
+ <span class="doccomment">/// Creates a unary expression with the given
operator and term.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use iceberg::expr::{PredicateOperator, Reference, UnaryExpression};
+ ///
+ /// UnaryExpression::new(PredicateOperator::IsNull, Reference::new("c"));
+ /// ```
+ </span><span class="kw">pub fn </span>new(op: PredicateOperator, term: T)
-> <span class="self">Self </span>{
<span class="macro">debug_assert!</span>(op.is_unary());
<span class="self">Self </span>{ op, term }
}
@@ -1458,7 +1490,21 @@
}
<span class="kw">impl</span><T> BinaryExpression<T> {
- <span class="kw">pub</span>(<span class="kw">crate</span>) <span
class="kw">fn </span>new(op: PredicateOperator, term: T, literal: Datum) ->
<span class="self">Self </span>{
+ <span class="doccomment">/// Creates a binary expression with the given
operator, term and literal.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use iceberg::expr::{BinaryExpression, PredicateOperator, Reference};
+ /// use iceberg::spec::Datum;
+ ///
+ /// BinaryExpression::new(
+ /// PredicateOperator::LessThanOrEq,
+ /// Reference::new("a"),
+ /// Datum::int(10),
+ /// );
+ /// ```
+ </span><span class="kw">pub fn </span>new(op: PredicateOperator, term: T,
literal: Datum) -> <span class="self">Self </span>{
<span class="macro">debug_assert!</span>(op.is_binary());
<span class="self">Self </span>{ op, term, literal }
}
diff --git a/api/src/iceberg_datafusion/physical_plan/expr_to_predicate.rs.html
b/api/src/iceberg_datafusion/physical_plan/expr_to_predicate.rs.html
index d68d3ae9..10ae61a4 100644
--- a/api/src/iceberg_datafusion/physical_plan/expr_to_predicate.rs.html
+++ b/api/src/iceberg_datafusion/physical_plan/expr_to_predicate.rs.html
@@ -333,6 +333,66 @@
<a href="#333" id="333">333</a>
<a href="#334" id="334">334</a>
<a href="#335" id="335">335</a>
+<a href="#336" id="336">336</a>
+<a href="#337" id="337">337</a>
+<a href="#338" id="338">338</a>
+<a href="#339" id="339">339</a>
+<a href="#340" id="340">340</a>
+<a href="#341" id="341">341</a>
+<a href="#342" id="342">342</a>
+<a href="#343" id="343">343</a>
+<a href="#344" id="344">344</a>
+<a href="#345" id="345">345</a>
+<a href="#346" id="346">346</a>
+<a href="#347" id="347">347</a>
+<a href="#348" id="348">348</a>
+<a href="#349" id="349">349</a>
+<a href="#350" id="350">350</a>
+<a href="#351" id="351">351</a>
+<a href="#352" id="352">352</a>
+<a href="#353" id="353">353</a>
+<a href="#354" id="354">354</a>
+<a href="#355" id="355">355</a>
+<a href="#356" id="356">356</a>
+<a href="#357" id="357">357</a>
+<a href="#358" id="358">358</a>
+<a href="#359" id="359">359</a>
+<a href="#360" id="360">360</a>
+<a href="#361" id="361">361</a>
+<a href="#362" id="362">362</a>
+<a href="#363" id="363">363</a>
+<a href="#364" id="364">364</a>
+<a href="#365" id="365">365</a>
+<a href="#366" id="366">366</a>
+<a href="#367" id="367">367</a>
+<a href="#368" id="368">368</a>
+<a href="#369" id="369">369</a>
+<a href="#370" id="370">370</a>
+<a href="#371" id="371">371</a>
+<a href="#372" id="372">372</a>
+<a href="#373" id="373">373</a>
+<a href="#374" id="374">374</a>
+<a href="#375" id="375">375</a>
+<a href="#376" id="376">376</a>
+<a href="#377" id="377">377</a>
+<a href="#378" id="378">378</a>
+<a href="#379" id="379">379</a>
+<a href="#380" id="380">380</a>
+<a href="#381" id="381">381</a>
+<a href="#382" id="382">382</a>
+<a href="#383" id="383">383</a>
+<a href="#384" id="384">384</a>
+<a href="#385" id="385">385</a>
+<a href="#386" id="386">386</a>
+<a href="#387" id="387">387</a>
+<a href="#388" id="388">388</a>
+<a href="#389" id="389">389</a>
+<a href="#390" id="390">390</a>
+<a href="#391" id="391">391</a>
+<a href="#392" id="392">392</a>
+<a href="#393" id="393">393</a>
+<a href="#394" id="394">394</a>
+<a href="#395" id="395">395</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
@@ -350,103 +410,179 @@
// specific language governing permissions and limitations
// under the License.
-</span><span class="kw">use </span>std::collections::VecDeque;
+</span><span class="kw">use </span>std::vec;
-<span class="kw">use </span>datafusion::common::tree_node::{TreeNodeRecursion,
TreeNodeVisitor};
-<span class="kw">use </span>datafusion::common::Column;
-<span class="kw">use </span>datafusion::error::DataFusionError;
<span class="kw">use </span>datafusion::logical_expr::{Expr, Operator};
<span class="kw">use </span>datafusion::scalar::ScalarValue;
-<span class="kw">use </span>iceberg::expr::{Predicate, Reference};
+<span class="kw">use </span>iceberg::expr::{BinaryExpression, Predicate,
PredicateOperator, Reference, UnaryExpression};
<span class="kw">use </span>iceberg::spec::Datum;
-<span class="kw">pub struct </span>ExprToPredicateVisitor {
- stack: VecDeque<<span
class="prelude-ty">Option</span><Predicate>>,
+<span class="comment">// A datafusion expression could be an Iceberg
predicate, column, or literal.
+</span><span class="kw">enum </span>TransformedResult {
+ Predicate(Predicate),
+ Column(Reference),
+ Literal(Datum),
+ NotTransformed,
}
-<span class="kw">impl </span>ExprToPredicateVisitor {
- <span class="doccomment">/// Create a new predicate conversion visitor.
- </span><span class="kw">pub fn </span>new() -> <span class="self">Self
</span>{
- <span class="self">Self </span>{
- stack: VecDeque::new(),
+
+<span class="kw">enum </span>OpTransformedResult {
+ Operator(PredicateOperator),
+ And,
+ Or,
+ NotTransformed,
+}
+
+<span class="doccomment">/// Converts DataFusion filters ([`Expr`]) to an
iceberg [`Predicate`].
+/// If none of the filters could be converted, return `None` which adds no
predicates to the scan operation.
+/// If the conversion was successful, return the converted predicates combined
with an AND operator.
+</span><span class="kw">pub fn </span>convert_filters_to_predicate(filters:
<span class="kw-2">&</span>[Expr]) -> <span
class="prelude-ty">Option</span><Predicate> {
+ filters
+ .iter()
+ .filter_map(convert_filter_to_predicate)
+ .reduce(Predicate::and)
+}
+
+<span class="kw">fn </span>convert_filter_to_predicate(expr: <span
class="kw-2">&</span>Expr) -> <span
class="prelude-ty">Option</span><Predicate> {
+ <span class="kw">match </span>to_iceberg_predicate(expr) {
+ TransformedResult::Predicate(predicate) => <span
class="prelude-val">Some</span>(predicate),
+ TransformedResult::Column(<span class="kw">_</span>) |
TransformedResult::Literal(<span class="kw">_</span>) => {
+ <span class="macro">unreachable!</span>(<span class="string">"Not
a valid expression: {:?}"</span>, expr)
}
+ <span class="kw">_ </span>=> <span class="prelude-val">None</span>,
}
- <span class="doccomment">/// Get the predicate from the stack.
- </span><span class="kw">pub fn </span>get_predicate(<span
class="kw-2">&</span><span class="self">self</span>) -> <span
class="prelude-ty">Option</span><Predicate> {
- <span class="self">self</span>.stack
- .iter()
- .filter_map(|opt| opt.clone())
- .reduce(Predicate::and)
+}
+
+<span class="kw">fn </span>to_iceberg_predicate(expr: <span
class="kw-2">&</span>Expr) -> TransformedResult {
+ <span class="kw">match </span>expr {
+ Expr::BinaryExpr(binary) => {
+ <span class="kw">let </span>left = to_iceberg_predicate(<span
class="kw-2">&</span>binary.left);
+ <span class="kw">let </span>right = to_iceberg_predicate(<span
class="kw-2">&</span>binary.right);
+ <span class="kw">let </span>op = to_iceberg_operation(binary.op);
+ <span class="kw">match </span>op {
+ OpTransformedResult::Operator(op) =>
to_iceberg_binary_predicate(left, right, op),
+ OpTransformedResult::And => to_iceberg_and_predicate(left,
right),
+ OpTransformedResult::Or => to_iceberg_or_predicate(left,
right),
+ OpTransformedResult::NotTransformed =>
TransformedResult::NotTransformed,
+ }
+ }
+ Expr::Not(exp) => {
+ <span class="kw">let </span>expr = to_iceberg_predicate(exp);
+ <span class="kw">match </span>expr {
+ TransformedResult::Predicate(p) =>
TransformedResult::Predicate(!p),
+ <span class="kw">_ </span>=>
TransformedResult::NotTransformed,
+ }
+ }
+ Expr::Column(column) =>
TransformedResult::Column(Reference::new(column.name())),
+ Expr::Literal(literal) => <span class="kw">match
</span>scalar_value_to_datum(literal) {
+ <span class="prelude-val">Some</span>(data) =>
TransformedResult::Literal(data),
+ <span class="prelude-val">None </span>=>
TransformedResult::NotTransformed,
+ },
+ Expr::InList(inlist) => {
+ <span class="kw">let </span><span class="kw-2">mut </span>datums =
<span class="macro">vec!</span>[];
+ <span class="kw">for </span>expr <span class="kw">in </span><span
class="kw-2">&</span>inlist.list {
+ <span class="kw">let </span>p = to_iceberg_predicate(expr);
+ <span class="kw">match </span>p {
+ TransformedResult::Literal(l) => datums.push(l),
+ <span class="kw">_ </span>=> <span class="kw">return
</span>TransformedResult::NotTransformed,
+ }
+ }
+
+ <span class="kw">let </span>expr = to_iceberg_predicate(<span
class="kw-2">&</span>inlist.expr);
+ <span class="kw">match </span>expr {
+ TransformedResult::Column(r) => <span class="kw">match
</span>inlist.negated {
+ <span class="bool-val">false </span>=>
TransformedResult::Predicate(r.is_in(datums)),
+ <span class="bool-val">true </span>=>
TransformedResult::Predicate(r.is_not_in(datums)),
+ },
+ <span class="kw">_ </span>=>
TransformedResult::NotTransformed,
+ }
+ }
+ Expr::IsNull(expr) => {
+ <span class="kw">let </span>p = to_iceberg_predicate(expr);
+ <span class="kw">match </span>p {
+ TransformedResult::Column(r) =>
TransformedResult::Predicate(Predicate::Unary(
+ UnaryExpression::new(PredicateOperator::IsNull, r),
+ )),
+ <span class="kw">_ </span>=>
TransformedResult::NotTransformed,
+ }
+ }
+ Expr::IsNotNull(expr) => {
+ <span class="kw">let </span>p = to_iceberg_predicate(expr);
+ <span class="kw">match </span>p {
+ TransformedResult::Column(r) =>
TransformedResult::Predicate(Predicate::Unary(
+ UnaryExpression::new(PredicateOperator::NotNull, r),
+ )),
+ <span class="kw">_ </span>=>
TransformedResult::NotTransformed,
+ }
+ }
+ <span class="kw">_ </span>=> TransformedResult::NotTransformed,
}
+}
- <span class="doccomment">/// Convert a column expression to an iceberg
predicate.
- </span><span class="kw">fn </span>convert_column_expr(
- <span class="kw-2">&</span><span class="self">self</span>,
- col: <span class="kw-2">&</span>Column,
- op: <span class="kw-2">&</span>Operator,
- lit: <span class="kw-2">&</span>ScalarValue,
- ) -> <span class="prelude-ty">Option</span><Predicate> {
- <span class="kw">let </span>reference =
Reference::new(col.name.clone());
- <span class="kw">let </span>datum = scalar_value_to_datum(lit)<span
class="question-mark">?</span>;
- <span
class="prelude-val">Some</span>(binary_op_to_predicate(reference, op, datum))
+<span class="kw">fn </span>to_iceberg_operation(op: Operator) ->
OpTransformedResult {
+ <span class="kw">match </span>op {
+ Operator::Eq =>
OpTransformedResult::Operator(PredicateOperator::Eq),
+ Operator::NotEq =>
OpTransformedResult::Operator(PredicateOperator::NotEq),
+ Operator::Lt =>
OpTransformedResult::Operator(PredicateOperator::LessThan),
+ Operator::LtEq =>
OpTransformedResult::Operator(PredicateOperator::LessThanOrEq),
+ Operator::Gt =>
OpTransformedResult::Operator(PredicateOperator::GreaterThan),
+ Operator::GtEq =>
OpTransformedResult::Operator(PredicateOperator::GreaterThanOrEq),
+ <span class="comment">// AND OR
+ </span>Operator::And => OpTransformedResult::And,
+ Operator::Or => OpTransformedResult::Or,
+ <span class="comment">// Others not supported
+ </span><span class="kw">_ </span>=>
OpTransformedResult::NotTransformed,
}
+}
- <span class="doccomment">/// Convert a compound expression to an iceberg
predicate.
- ///
- /// The strategy is to support the following cases:
- /// - if its an AND expression then the result will be the valid
predicates, whether there are 2 or just 1
- /// - if its an OR expression then a predicate will be returned only if
there are 2 valid predicates on both sides
- </span><span class="kw">fn </span>convert_compound_expr(<span
class="kw-2">&</span><span class="self">self</span>, valid_preds: <span
class="kw-2">&</span>[Predicate], op: <span
class="kw-2">&</span>Operator) -> <span
class="prelude-ty">Option</span><Predicate> {
- <span class="kw">let </span>valid_preds_count = valid_preds.len();
- <span class="kw">match </span>(op, valid_preds_count) {
- (Operator::And, <span class="number">1</span>) =>
valid_preds.first().cloned(),
- (Operator::And, <span class="number">2</span>) => <span
class="prelude-val">Some</span>(Predicate::and(
- valid_preds[<span class="number">0</span>].clone(),
- valid_preds[<span class="number">1</span>].clone(),
- )),
- (Operator::Or, <span class="number">2</span>) => <span
class="prelude-val">Some</span>(Predicate::or(
- valid_preds[<span class="number">0</span>].clone(),
- valid_preds[<span class="number">1</span>].clone(),
- )),
- <span class="kw">_ </span>=> <span
class="prelude-val">None</span>,
+<span class="kw">fn </span>to_iceberg_and_predicate(
+ left: TransformedResult,
+ right: TransformedResult,
+) -> TransformedResult {
+ <span class="kw">match </span>(left, right) {
+ (TransformedResult::Predicate(left),
TransformedResult::Predicate(right)) => {
+ TransformedResult::Predicate(left.and(right))
}
+ (TransformedResult::Predicate(left), <span class="kw">_</span>) =>
TransformedResult::Predicate(left),
+ (<span class="kw">_</span>, TransformedResult::Predicate(right)) =>
TransformedResult::Predicate(right),
+ <span class="kw">_ </span>=> TransformedResult::NotTransformed,
}
}
-<span class="comment">// Implement TreeNodeVisitor for ExprToPredicateVisitor
-</span><span class="kw">impl</span><<span class="lifetime">'n</span>>
TreeNodeVisitor<<span class="lifetime">'n</span>> <span class="kw">for
</span>ExprToPredicateVisitor {
- <span class="kw">type </span>Node = Expr;
-
- <span class="kw">fn </span>f_down(<span class="kw-2">&mut </span><span
class="self">self</span>, _node: <span class="kw-2">&</span><span
class="lifetime">'n </span>Expr) -> <span
class="prelude-ty">Result</span><TreeNodeRecursion, DataFusionError> {
- <span class="prelude-val">Ok</span>(TreeNodeRecursion::Continue)
+<span class="kw">fn </span>to_iceberg_or_predicate(left: TransformedResult,
right: TransformedResult) -> TransformedResult {
+ <span class="kw">match </span>(left, right) {
+ (TransformedResult::Predicate(left),
TransformedResult::Predicate(right)) => {
+ TransformedResult::Predicate(left.or(right))
+ }
+ <span class="kw">_ </span>=> TransformedResult::NotTransformed,
}
+}
- <span class="kw">fn </span>f_up(<span class="kw-2">&mut </span><span
class="self">self</span>, expr: <span class="kw-2">&</span><span
class="lifetime">'n </span>Expr) -> <span
class="prelude-ty">Result</span><TreeNodeRecursion, DataFusionError> {
- <span class="kw">if let </span>Expr::BinaryExpr(binary) = expr {
- <span class="kw">match </span>(<span
class="kw-2">&*</span>binary.left, <span
class="kw-2">&</span>binary.op, <span
class="kw-2">&*</span>binary.right) {
- <span class="comment">// process simple binary expressions,
e.g. col > 1
- </span>(Expr::Column(col), op, Expr::Literal(lit)) => {
- <span class="kw">let </span>col_pred = <span
class="self">self</span>.convert_column_expr(col, op, lit);
- <span class="self">self</span>.stack.push_back(col_pred);
- }
- <span class="comment">// // process reversed binary
expressions, e.g. 1 < col
- </span>(Expr::Literal(lit), op, Expr::Column(col)) => {
- <span class="kw">let </span>col_pred = op
- .swap()
- .and_then(|negated_op| <span
class="self">self</span>.convert_column_expr(col, <span
class="kw-2">&</span>negated_op, lit));
- <span class="self">self</span>.stack.push_back(col_pred);
- }
- <span class="comment">// process compound expressions
(involving logical operators. e.g., AND or OR and children)
- </span>(_left, op, _right) <span class="kw">if
</span>op.is_logic_operator() => {
- <span class="kw">let </span>right_pred = <span
class="self">self</span>.stack.pop_back().flatten();
- <span class="kw">let </span>left_pred = <span
class="self">self</span>.stack.pop_back().flatten();
- <span class="kw">let </span>children: Vec<<span
class="kw">_</span>> = [left_pred,
right_pred].into_iter().flatten().collect();
- <span class="kw">let </span>compound_pred = <span
class="self">self</span>.convert_compound_expr(<span
class="kw-2">&</span>children, op);
- <span
class="self">self</span>.stack.push_back(compound_pred);
- }
- <span class="kw">_ </span>=> <span class="kw">return
</span><span class="prelude-val">Ok</span>(TreeNodeRecursion::Continue),
- }
+<span class="kw">fn </span>to_iceberg_binary_predicate(
+ left: TransformedResult,
+ right: TransformedResult,
+ op: PredicateOperator,
+) -> TransformedResult {
+ <span class="kw">let </span>(r, d, op) = <span class="kw">match
</span>(left, right) {
+ (TransformedResult::NotTransformed, <span class="kw">_</span>) =>
<span class="kw">return </span>TransformedResult::NotTransformed,
+ (<span class="kw">_</span>, TransformedResult::NotTransformed) =>
<span class="kw">return </span>TransformedResult::NotTransformed,
+ (TransformedResult::Column(r), TransformedResult::Literal(d)) =>
(r, d, op),
+ (TransformedResult::Literal(d), TransformedResult::Column(r)) => {
+ (r, d, reverse_predicate_operator(op))
}
- <span class="prelude-val">Ok</span>(TreeNodeRecursion::Continue)
+ <span class="kw">_ </span>=> <span class="kw">return
</span>TransformedResult::NotTransformed,
+ };
+ TransformedResult::Predicate(Predicate::Binary(BinaryExpression::new(op,
r, d)))
+}
+
+<span class="kw">fn </span>reverse_predicate_operator(op: PredicateOperator)
-> PredicateOperator {
+ <span class="kw">match </span>op {
+ PredicateOperator::Eq => PredicateOperator::Eq,
+ PredicateOperator::NotEq => PredicateOperator::NotEq,
+ PredicateOperator::GreaterThan => PredicateOperator::LessThan,
+ PredicateOperator::GreaterThanOrEq =>
PredicateOperator::LessThanOrEq,
+ PredicateOperator::LessThan => PredicateOperator::GreaterThan,
+ PredicateOperator::LessThanOrEq =>
PredicateOperator::GreaterThanOrEq,
+ <span class="kw">_ </span>=> <span
class="macro">unreachable!</span>(<span class="string">"Reverse {}"</span>, op),
}
}
@@ -468,93 +604,113 @@
}
}
-<span class="doccomment">/// convert the data fusion Exp to an iceberg
[`Predicate`]
-</span><span class="kw">fn </span>binary_op_to_predicate(reference: Reference,
op: <span class="kw-2">&</span>Operator, datum: Datum) -> Predicate {
- <span class="kw">match </span>op {
- Operator::Eq => reference.equal_to(datum),
- Operator::NotEq => reference.not_equal_to(datum),
- Operator::Lt => reference.less_than(datum),
- Operator::LtEq => reference.less_than_or_equal_to(datum),
- Operator::Gt => reference.greater_than(datum),
- Operator::GtEq => reference.greater_than_or_equal_to(datum),
- <span class="kw">_ </span>=> Predicate::AlwaysTrue,
- }
-}
-
<span class="attr">#[cfg(test)]
</span><span class="kw">mod </span>tests {
- <span class="kw">use </span>std::collections::VecDeque;
-
<span class="kw">use </span>datafusion::arrow::datatypes::{DataType,
Field, Schema};
- <span class="kw">use </span>datafusion::common::tree_node::TreeNode;
<span class="kw">use </span>datafusion::common::DFSchema;
- <span class="kw">use </span>datafusion::prelude::SessionContext;
+ <span class="kw">use
</span>datafusion::logical_expr::utils::split_conjunction;
+ <span class="kw">use </span>datafusion::prelude::{Expr, SessionContext};
<span class="kw">use </span>iceberg::expr::{Predicate, Reference};
<span class="kw">use </span>iceberg::spec::Datum;
- <span class="kw">use </span><span
class="kw">super</span>::ExprToPredicateVisitor;
+ <span class="kw">use </span><span
class="kw">super</span>::convert_filters_to_predicate;
<span class="kw">fn </span>create_test_schema() -> DFSchema {
<span class="kw">let </span>arrow_schema = Schema::new(<span
class="macro">vec!</span>[
- Field::new(<span class="string">"foo"</span>, DataType::Int32,
<span class="bool-val">false</span>),
- Field::new(<span class="string">"bar"</span>, DataType::Utf8,
<span class="bool-val">false</span>),
+ Field::new(<span class="string">"foo"</span>, DataType::Int32,
<span class="bool-val">true</span>),
+ Field::new(<span class="string">"bar"</span>, DataType::Utf8,
<span class="bool-val">true</span>),
]);
DFSchema::try_from_qualified_schema(<span
class="string">"my_table"</span>, <span
class="kw-2">&</span>arrow_schema).unwrap()
}
- <span class="attr">#[test]
- </span><span class="kw">fn
</span>test_predicate_conversion_with_single_condition() {
- <span class="kw">let </span>sql = <span class="string">"foo >
1"</span>;
+ <span class="kw">fn </span>convert_to_iceberg_predicate(sql: <span
class="kw-2">&</span>str) -> <span
class="prelude-ty">Option</span><Predicate> {
<span class="kw">let </span>df_schema = create_test_schema();
<span class="kw">let </span>expr = SessionContext::new()
.parse_sql_expr(sql, <span class="kw-2">&</span>df_schema)
.unwrap();
- <span class="kw">let </span><span class="kw-2">mut </span>visitor =
ExprToPredicateVisitor::new();
- expr.visit(<span class="kw-2">&mut </span>visitor).unwrap();
- <span class="kw">let </span>predicate =
visitor.get_predicate().unwrap();
+ <span class="kw">let </span>exprs: Vec<Expr> =
split_conjunction(<span
class="kw-2">&</span>expr).into_iter().cloned().collect();
+ convert_filters_to_predicate(<span class="kw-2">&</span>exprs[..])
+ }
+
+ <span class="attr">#[test]
+ </span><span class="kw">fn
</span>test_predicate_conversion_with_single_condition() {
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(<span class="string">"foo = 1"</span>).unwrap();
+ <span class="macro">assert_eq!</span>(predicate, Reference::new(<span
class="string">"foo"</span>).equal_to(Datum::long(<span
class="number">1</span>)));
+
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(<span class="string">"foo != 1"</span>).unwrap();
+ <span class="macro">assert_eq!</span>(
+ predicate,
+ Reference::new(<span
class="string">"foo"</span>).not_equal_to(Datum::long(<span
class="number">1</span>))
+ );
+
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(<span class="string">"foo > 1"</span>).unwrap();
<span class="macro">assert_eq!</span>(
predicate,
Reference::new(<span
class="string">"foo"</span>).greater_than(Datum::long(<span
class="number">1</span>))
);
+
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(<span class="string">"foo >=
1"</span>).unwrap();
+ <span class="macro">assert_eq!</span>(
+ predicate,
+ Reference::new(<span
class="string">"foo"</span>).greater_than_or_equal_to(Datum::long(<span
class="number">1</span>))
+ );
+
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(<span class="string">"foo < 1"</span>).unwrap();
+ <span class="macro">assert_eq!</span>(predicate, Reference::new(<span
class="string">"foo"</span>).less_than(Datum::long(<span
class="number">1</span>)));
+
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(<span class="string">"foo <=
1"</span>).unwrap();
+ <span class="macro">assert_eq!</span>(
+ predicate,
+ Reference::new(<span
class="string">"foo"</span>).less_than_or_equal_to(Datum::long(<span
class="number">1</span>))
+ );
+
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(<span class="string">"foo is
null"</span>).unwrap();
+ <span class="macro">assert_eq!</span>(predicate, Reference::new(<span
class="string">"foo"</span>).is_null());
+
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(<span class="string">"foo is not
null"</span>).unwrap();
+ <span class="macro">assert_eq!</span>(predicate, Reference::new(<span
class="string">"foo"</span>).is_not_null());
+
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(<span class="string">"foo in (5,
6)"</span>).unwrap();
+ <span class="macro">assert_eq!</span>(
+ predicate,
+ Reference::new(<span
class="string">"foo"</span>).is_in([Datum::long(<span class="number">5</span>),
Datum::long(<span class="number">6</span>)])
+ );
+
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(<span class="string">"foo not in (5,
6)"</span>).unwrap();
+ <span class="macro">assert_eq!</span>(
+ predicate,
+ Reference::new(<span
class="string">"foo"</span>).is_not_in([Datum::long(<span
class="number">5</span>), Datum::long(<span class="number">6</span>)])
+ );
+
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(<span class="string">"not foo =
1"</span>).unwrap();
+ <span class="macro">assert_eq!</span>(predicate, !Reference::new(<span
class="string">"foo"</span>).equal_to(Datum::long(<span
class="number">1</span>)));
}
+
<span class="attr">#[test]
</span><span class="kw">fn
</span>test_predicate_conversion_with_single_unsupported_condition() {
- <span class="kw">let </span>sql = <span class="string">"foo is
null"</span>;
- <span class="kw">let </span>df_schema = create_test_schema();
- <span class="kw">let </span>expr = SessionContext::new()
- .parse_sql_expr(sql, <span class="kw-2">&</span>df_schema)
- .unwrap();
- <span class="kw">let </span><span class="kw-2">mut </span>visitor =
ExprToPredicateVisitor::new();
- expr.visit(<span class="kw-2">&mut </span>visitor).unwrap();
- <span class="kw">let </span>predicate = visitor.get_predicate();
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(<span class="string">"foo + 1 = 1"</span>);
+ <span class="macro">assert_eq!</span>(predicate, <span
class="prelude-val">None</span>);
+
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(<span class="string">"length(bar) = 1"</span>);
+ <span class="macro">assert_eq!</span>(predicate, <span
class="prelude-val">None</span>);
+
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(<span class="string">"foo in (1, 2, foo)"</span>);
<span class="macro">assert_eq!</span>(predicate, <span
class="prelude-val">None</span>);
}
<span class="attr">#[test]
</span><span class="kw">fn
</span>test_predicate_conversion_with_single_condition_rev() {
- <span class="kw">let </span>sql = <span class="string">"1 <
foo"</span>;
- <span class="kw">let </span>df_schema = create_test_schema();
- <span class="kw">let </span>expr = SessionContext::new()
- .parse_sql_expr(sql, <span class="kw-2">&</span>df_schema)
- .unwrap();
- <span class="kw">let </span><span class="kw-2">mut </span>visitor =
ExprToPredicateVisitor::new();
- expr.visit(<span class="kw-2">&mut </span>visitor).unwrap();
- <span class="kw">let </span>predicate =
visitor.get_predicate().unwrap();
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(<span class="string">"1 < foo"</span>).unwrap();
<span class="macro">assert_eq!</span>(
predicate,
Reference::new(<span
class="string">"foo"</span>).greater_than(Datum::long(<span
class="number">1</span>))
);
}
+
<span class="attr">#[test]
</span><span class="kw">fn
</span>test_predicate_conversion_with_and_condition() {
<span class="kw">let </span>sql = <span class="string">"foo > 1 and
bar = 'test'"</span>;
- <span class="kw">let </span>df_schema = create_test_schema();
- <span class="kw">let </span>expr = SessionContext::new()
- .parse_sql_expr(sql, <span class="kw-2">&</span>df_schema)
- .unwrap();
- <span class="kw">let </span><span class="kw-2">mut </span>visitor =
ExprToPredicateVisitor::new();
- expr.visit(<span class="kw-2">&mut </span>visitor).unwrap();
- <span class="kw">let </span>predicate =
visitor.get_predicate().unwrap();
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(sql).unwrap();
<span class="kw">let </span>expected_predicate = Predicate::and(
Reference::new(<span
class="string">"foo"</span>).greater_than(Datum::long(<span
class="number">1</span>)),
Reference::new(<span
class="string">"bar"</span>).equal_to(Datum::string(<span
class="string">"test"</span>)),
@@ -564,55 +720,42 @@
<span class="attr">#[test]
</span><span class="kw">fn
</span>test_predicate_conversion_with_and_condition_unsupported() {
- <span class="kw">let </span>sql = <span class="string">"foo > 1 and
bar is not null"</span>;
- <span class="kw">let </span>df_schema = create_test_schema();
- <span class="kw">let </span>expr = SessionContext::new()
- .parse_sql_expr(sql, <span class="kw-2">&</span>df_schema)
- .unwrap();
- <span class="kw">let </span><span class="kw-2">mut </span>visitor =
ExprToPredicateVisitor::new();
- expr.visit(<span class="kw-2">&mut </span>visitor).unwrap();
- <span class="kw">let </span>predicate =
visitor.get_predicate().unwrap();
+ <span class="kw">let </span>sql = <span class="string">"foo > 1 and
length(bar) = 1"</span>;
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(sql).unwrap();
<span class="kw">let </span>expected_predicate = Reference::new(<span
class="string">"foo"</span>).greater_than(Datum::long(<span
class="number">1</span>));
<span class="macro">assert_eq!</span>(predicate, expected_predicate);
}
+
<span class="attr">#[test]
</span><span class="kw">fn
</span>test_predicate_conversion_with_and_condition_both_unsupported() {
- <span class="kw">let </span>sql = <span class="string">"foo in (1, 2,
3) and bar is not null"</span>;
- <span class="kw">let </span>df_schema = create_test_schema();
- <span class="kw">let </span>expr = SessionContext::new()
- .parse_sql_expr(sql, <span class="kw-2">&</span>df_schema)
- .unwrap();
- <span class="kw">let </span><span class="kw-2">mut </span>visitor =
ExprToPredicateVisitor::new();
- expr.visit(<span class="kw-2">&mut </span>visitor).unwrap();
- <span class="kw">let </span>predicate = visitor.get_predicate();
- <span class="kw">let </span>expected_predicate = <span
class="prelude-val">None</span>;
- <span class="macro">assert_eq!</span>(predicate, expected_predicate);
+ <span class="kw">let </span>sql = <span class="string">"foo in (1, 2,
foo) and length(bar) = 1"</span>;
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(sql);
+ <span class="macro">assert_eq!</span>(predicate, <span
class="prelude-val">None</span>);
}
<span class="attr">#[test]
</span><span class="kw">fn
</span>test_predicate_conversion_with_or_condition_unsupported() {
- <span class="kw">let </span>sql = <span class="string">"foo > 1 or
bar is not null"</span>;
- <span class="kw">let </span>df_schema = create_test_schema();
- <span class="kw">let </span>expr = SessionContext::new()
- .parse_sql_expr(sql, <span class="kw-2">&</span>df_schema)
- .unwrap();
- <span class="kw">let </span><span class="kw-2">mut </span>visitor =
ExprToPredicateVisitor::new();
- expr.visit(<span class="kw-2">&mut </span>visitor).unwrap();
- <span class="kw">let </span>predicate = visitor.get_predicate();
- <span class="kw">let </span>expected_predicate = <span
class="prelude-val">None</span>;
+ <span class="kw">let </span>sql = <span class="string">"foo > 1 or
length(bar) = 1"</span>;
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(sql);
+ <span class="macro">assert_eq!</span>(predicate, <span
class="prelude-val">None</span>);
+ }
+
+ <span class="attr">#[test]
+ </span><span class="kw">fn
</span>test_predicate_conversion_with_or_condition_supported() {
+ <span class="kw">let </span>sql = <span class="string">"foo > 1 or
bar = 'test'"</span>;
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(sql).unwrap();
+ <span class="kw">let </span>expected_predicate = Predicate::or(
+ Reference::new(<span
class="string">"foo"</span>).greater_than(Datum::long(<span
class="number">1</span>)),
+ Reference::new(<span
class="string">"bar"</span>).equal_to(Datum::string(<span
class="string">"test"</span>)),
+ );
<span class="macro">assert_eq!</span>(predicate, expected_predicate);
}
<span class="attr">#[test]
</span><span class="kw">fn
</span>test_predicate_conversion_with_complex_binary_expr() {
<span class="kw">let </span>sql = <span class="string">"(foo > 1
and bar = 'test') or foo < 0 "</span>;
- <span class="kw">let </span>df_schema = create_test_schema();
- <span class="kw">let </span>expr = SessionContext::new()
- .parse_sql_expr(sql, <span class="kw-2">&</span>df_schema)
- .unwrap();
- <span class="kw">let </span><span class="kw-2">mut </span>visitor =
ExprToPredicateVisitor::new();
- expr.visit(<span class="kw-2">&mut </span>visitor).unwrap();
- <span class="kw">let </span>predicate =
visitor.get_predicate().unwrap();
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(sql).unwrap();
+
<span class="kw">let </span>inner_predicate = Predicate::and(
Reference::new(<span
class="string">"foo"</span>).greater_than(Datum::long(<span
class="number">1</span>)),
Reference::new(<span
class="string">"bar"</span>).equal_to(Datum::string(<span
class="string">"test"</span>)),
@@ -625,47 +768,24 @@
}
<span class="attr">#[test]
- </span><span class="kw">fn
</span>test_predicate_conversion_with_complex_binary_expr_unsupported() {
- <span class="kw">let </span>sql = <span class="string">"(foo > 1 or
bar in ('test', 'test2')) and foo < 0 "</span>;
- <span class="kw">let </span>df_schema = create_test_schema();
- <span class="kw">let </span>expr = SessionContext::new()
- .parse_sql_expr(sql, <span class="kw-2">&</span>df_schema)
- .unwrap();
- <span class="kw">let </span><span class="kw-2">mut </span>visitor =
ExprToPredicateVisitor::new();
- expr.visit(<span class="kw-2">&mut </span>visitor).unwrap();
- <span class="kw">let </span>predicate =
visitor.get_predicate().unwrap();
- <span class="kw">let </span>expected_predicate = Reference::new(<span
class="string">"foo"</span>).less_than(Datum::long(<span
class="number">0</span>));
- <span class="macro">assert_eq!</span>(predicate, expected_predicate);
- }
+ </span><span class="kw">fn
</span>test_predicate_conversion_with_one_and_expr_supported() {
+ <span class="kw">let </span>sql = <span class="string">"(foo > 1
and length(bar) = 1 ) or foo < 0 "</span>;
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(sql).unwrap();
- <span class="attr">#[test]
- </span><span class="comment">// test the get result method
- </span><span class="kw">fn </span>test_get_result_multiple() {
- <span class="kw">let </span>predicates = <span
class="macro">vec!</span>[
- <span class="prelude-val">Some</span>(Reference::new(<span
class="string">"foo"</span>).greater_than(Datum::long(<span
class="number">1</span>))),
- <span class="prelude-val">None</span>,
- <span class="prelude-val">Some</span>(Reference::new(<span
class="string">"bar"</span>).equal_to(Datum::string(<span
class="string">"test"</span>))),
- ];
- <span class="kw">let </span>stack = VecDeque::from(predicates);
- <span class="kw">let </span>visitor = ExprToPredicateVisitor { stack };
- <span class="macro">assert_eq!</span>(
- visitor.get_predicate(),
- <span class="prelude-val">Some</span>(Predicate::and(
- Reference::new(<span
class="string">"foo"</span>).greater_than(Datum::long(<span
class="number">1</span>)),
- Reference::new(<span
class="string">"bar"</span>).equal_to(Datum::string(<span
class="string">"test"</span>)),
- ))
+ <span class="kw">let </span>inner_predicate = Reference::new(<span
class="string">"foo"</span>).greater_than(Datum::long(<span
class="number">1</span>));
+ <span class="kw">let </span>expected_predicate = Predicate::or(
+ inner_predicate,
+ Reference::new(<span
class="string">"foo"</span>).less_than(Datum::long(<span
class="number">0</span>)),
);
+ <span class="macro">assert_eq!</span>(predicate, expected_predicate);
}
<span class="attr">#[test]
- </span><span class="kw">fn </span>test_get_result_single() {
- <span class="kw">let </span>predicates = <span
class="macro">vec!</span>[<span
class="prelude-val">Some</span>(Reference::new(<span
class="string">"foo"</span>).greater_than(Datum::long(<span
class="number">1</span>)))];
- <span class="kw">let </span>stack = VecDeque::from(predicates);
- <span class="kw">let </span>visitor = ExprToPredicateVisitor { stack };
- <span class="macro">assert_eq!</span>(
- visitor.get_predicate(),
- <span class="prelude-val">Some</span>(Reference::new(<span
class="string">"foo"</span>).greater_than(Datum::long(<span
class="number">1</span>)))
- );
+ </span><span class="kw">fn
</span>test_predicate_conversion_with_complex_binary_expr_unsupported() {
+ <span class="kw">let </span>sql = <span class="string">"(foo > 1 or
length(bar) = 1 ) and foo < 0 "</span>;
+ <span class="kw">let </span>predicate =
convert_to_iceberg_predicate(sql).unwrap();
+ <span class="kw">let </span>expected_predicate = Reference::new(<span
class="string">"foo"</span>).less_than(Datum::long(<span
class="number">0</span>));
+ <span class="macro">assert_eq!</span>(predicate, expected_predicate);
}
}
</code></pre></div></section></main></body></html>
\ No newline at end of file
diff --git a/api/src/iceberg_datafusion/physical_plan/scan.rs.html
b/api/src/iceberg_datafusion/physical_plan/scan.rs.html
index 3237156b..c2e33392 100644
--- a/api/src/iceberg_datafusion/physical_plan/scan.rs.html
+++ b/api/src/iceberg_datafusion/physical_plan/scan.rs.html
@@ -187,20 +187,6 @@
<a href="#187" id="187">187</a>
<a href="#188" id="188">188</a>
<a href="#189" id="189">189</a>
-<a href="#190" id="190">190</a>
-<a href="#191" id="191">191</a>
-<a href="#192" id="192">192</a>
-<a href="#193" id="193">193</a>
-<a href="#194" id="194">194</a>
-<a href="#195" id="195">195</a>
-<a href="#196" id="196">196</a>
-<a href="#197" id="197">197</a>
-<a href="#198" id="198">198</a>
-<a href="#199" id="199">199</a>
-<a href="#200" id="200">200</a>
-<a href="#201" id="201">201</a>
-<a href="#202" id="202">202</a>
-<a href="#203" id="203">203</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
@@ -225,7 +211,6 @@
<span class="kw">use </span>datafusion::arrow::array::RecordBatch;
<span class="kw">use </span>datafusion::arrow::datatypes::SchemaRef <span
class="kw">as </span>ArrowSchemaRef;
-<span class="kw">use </span>datafusion::common::tree_node::TreeNode;
<span class="kw">use </span>datafusion::error::Result <span class="kw">as
</span>DFResult;
<span class="kw">use </span>datafusion::execution::{SendableRecordBatchStream,
TaskContext};
<span class="kw">use </span>datafusion::physical_expr::EquivalenceProperties;
@@ -238,7 +223,7 @@
<span class="kw">use </span>iceberg::expr::Predicate;
<span class="kw">use </span>iceberg::table::Table;
-<span class="kw">use </span><span
class="kw">crate</span>::physical_plan::expr_to_predicate::ExprToPredicateVisitor;
+<span class="kw">use </span><span
class="kw">super</span>::expr_to_predicate::convert_filters_to_predicate;
<span class="kw">use </span><span class="kw">crate</span>::to_datafusion_error;
<span class="doccomment">/// Manages the scanning process of an Iceberg
[`Table`], encapsulating the
@@ -343,10 +328,13 @@
) -> std::fmt::Result {
<span class="macro">write!</span>(
f,
- <span class="string">"IcebergTableScan projection:[{}]"</span>,
+ <span class="string">"IcebergTableScan projection:[{}]
predicate:[{}]"</span>,
<span class="self">self</span>.projection
.clone()
- .map_or(String::new(), |v| v.join(<span
class="string">","</span>))
+ .map_or(String::new(), |v| v.join(<span
class="string">","</span>)),
+ <span class="self">self</span>.predicates
+ .clone()
+ .map_or(String::from(<span class="string">""</span>), |p|
<span class="macro">format!</span>(<span class="string">"{}"</span>, p))
)
}
}
@@ -378,22 +366,6 @@
<span class="prelude-val">Ok</span>(Box::pin(stream))
}
-<span class="doccomment">/// Converts DataFusion filters ([`Expr`]) to an
iceberg [`Predicate`].
-/// If none of the filters could be converted, return `None` which adds no
predicates to the scan operation.
-/// If the conversion was successful, return the converted predicates combined
with an AND operator.
-</span><span class="kw">fn </span>convert_filters_to_predicate(filters: <span
class="kw-2">&</span>[Expr]) -> <span
class="prelude-ty">Option</span><Predicate> {
- filters
- .iter()
- .filter_map(|expr| {
- <span class="kw">let </span><span class="kw-2">mut </span>visitor
= ExprToPredicateVisitor::new();
- <span class="kw">if </span>expr.visit(<span class="kw-2">&mut
</span>visitor).is_ok() {
- visitor.get_predicate()
- } <span class="kw">else </span>{
- <span class="prelude-val">None
- </span>}
- })
- .reduce(Predicate::and)
-}
<span class="kw">fn </span>get_column_names(
schema: ArrowSchemaRef,
projection: <span class="prelude-ty">Option</span><<span
class="kw-2">&</span>Vec<usize>>,
diff --git a/api/src/iceberg_datafusion/table.rs.html
b/api/src/iceberg_datafusion/table.rs.html
index afca1bfc..9485734a 100644
--- a/api/src/iceberg_datafusion/table.rs.html
+++ b/api/src/iceberg_datafusion/table.rs.html
@@ -157,13 +157,6 @@
<a href="#157" id="157">157</a>
<a href="#158" id="158">158</a>
<a href="#159" id="159">159</a>
-<a href="#160" id="160">160</a>
-<a href="#161" id="161">161</a>
-<a href="#162" id="162">162</a>
-<a href="#163" id="163">163</a>
-<a href="#164" id="164">164</a>
-<a href="#165" id="165">165</a>
-<a href="#166" id="166">166</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
@@ -189,7 +182,7 @@
<span class="kw">use </span>datafusion::catalog::Session;
<span class="kw">use </span>datafusion::datasource::{TableProvider, TableType};
<span class="kw">use </span>datafusion::error::Result <span class="kw">as
</span>DFResult;
-<span class="kw">use </span>datafusion::logical_expr::{BinaryExpr, Expr,
TableProviderFilterPushDown};
+<span class="kw">use </span>datafusion::logical_expr::{Expr,
TableProviderFilterPushDown};
<span class="kw">use </span>datafusion::physical_plan::ExecutionPlan;
<span class="kw">use </span>iceberg::arrow::schema_to_arrow_schema;
<span class="kw">use </span>iceberg::table::Table;
@@ -265,15 +258,8 @@
filters: <span class="kw-2">&</span>[<span
class="kw-2">&</span>Expr],
) -> std::result::Result<Vec<TableProviderFilterPushDown>,
datafusion::error::DataFusionError>
{
- <span class="kw">let </span>filter_support = filters
- .iter()
- .map(|e| <span class="kw">match </span>e {
- Expr::BinaryExpr(BinaryExpr { .. }) =>
TableProviderFilterPushDown::Inexact,
- <span class="kw">_ </span>=>
TableProviderFilterPushDown::Unsupported,
- })
- .collect::<Vec<TableProviderFilterPushDown>>();
-
- <span class="prelude-val">Ok</span>(filter_support)
+ <span class="comment">// Push down all filters, as a single source of
truth, the scanner will drop the filters which couldn't be push down
+ </span><span class="prelude-val">Ok</span>(<span
class="macro">vec!</span>[TableProviderFilterPushDown::Inexact; filters.len()])
}
}