Skip to content

Conversation

friendlymatthew
Copy link
Contributor

@friendlymatthew friendlymatthew commented Oct 14, 2025

Which issue does this PR close?

This PR introduces an Iterator over VariantArray. Since VariantArray does not impl Array, we can't make use of ArrayIter

@github-actions github-actions bot added the parquet-variant parquet-variant* crates label Oct 14, 2025
@friendlymatthew friendlymatthew force-pushed the friendlymatthew/impl-array-for-variant-array branch from a5da641 to f8c109b Compare October 14, 2025 17:00
@github-actions github-actions bot added the parquet Changes to the parquet crate label Oct 14, 2025
@friendlymatthew friendlymatthew force-pushed the friendlymatthew/impl-array-for-variant-array branch 2 times, most recently from afa37a5 to a254af8 Compare October 14, 2025 17:03
@kylebarron
Copy link
Member

For context this was removed in #8392

@friendlymatthew friendlymatthew force-pushed the friendlymatthew/impl-array-for-variant-array branch from a254af8 to 3cdd28b Compare October 14, 2025 17:43
@github-actions github-actions bot removed the parquet Changes to the parquet crate label Oct 14, 2025
@friendlymatthew friendlymatthew changed the title [Variant] Impl arrow::Array for VariantArray [Variant] Make VariantArray iterable Oct 14, 2025
@friendlymatthew
Copy link
Contributor Author

friendlymatthew commented Oct 14, 2025

For context this was removed in #8392

Thanks for clarifying

@friendlymatthew friendlymatthew force-pushed the friendlymatthew/impl-array-for-variant-array branch 3 times, most recently from e188b4b to d65a5c3 Compare October 14, 2025 17:59
@friendlymatthew
Copy link
Contributor Author

friendlymatthew commented Oct 14, 2025

cc @scovich @alamb

Copy link
Contributor

@alamb alamb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! this looks very useful to me -- thanks @friendlymatthew


/// An iterator over [`VariantArray`]
///
/// This iterator returns `Option<Option<Variant<'a, 'a>>>` where:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you for the comments

out
}

fn size_hint(&self) -> (usize, Option<usize>) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I double checked the definition of size_hint and this looks good:

https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.size_hint

Copy link
Contributor

@scovich scovich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice! One code cleanup to consider.

Comment on lines 497 to 509
if self.head_i == self.tail_i {
return None;
}

let out = if self.is_null(self.head_i) {
Some(None)
} else {
Some(Some(self.array.value(self.head_i)))
};

self.head_i += 1;

out
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if self.head_i == self.tail_i {
return None;
}
let out = if self.is_null(self.head_i) {
Some(None)
} else {
Some(Some(self.array.value(self.head_i)))
};
self.head_i += 1;
out
(self.head_i < self.tail_i)
.then(|| self.value_opt(self.head_i))
.inspect(|_| self.head_i += 1)

(same story for DoubleEndedIterator below)

Copy link
Contributor Author

@friendlymatthew friendlymatthew Oct 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi hi, I think using combinators are great, but in this case we're 1) hurting readability and 2) using Option::inspect to mutate state

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree the inspect call was too clever, but why would this hurt readability?

        (self.head_i < self.tail_i).then(|| {
            let out = self.value_opt(self.head_i);
            self.head_i += 1;
            out
        })

Copy link
Contributor Author

@friendlymatthew friendlymatthew Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think cases like the following are completely valid and very readable. It's simply inspecting the state

(self.head_i < self.tail_i).then(|| self.value_opt(self.head_i)); 

In the closure you posted above, I'm just a bit surprised as a reader that the closure is inspecting the state and mutating it. Plus, I think the following form is simpler to reason through

// base case
if self.head_i == self.tail_i {
    return None;
}

// else
let out = self.value_opt(self.head_i);
self.head_i += 1;

Some(out)

But then again, it's just personal preference. I don't think there's anything wrong with either approach

@friendlymatthew friendlymatthew force-pushed the friendlymatthew/impl-array-for-variant-array branch from d65a5c3 to 3c5bcd4 Compare October 14, 2025 23:02
@alamb
Copy link
Contributor

alamb commented Oct 15, 2025

Thanks @scovich and @friendlymatthew

@alamb alamb merged commit 52f7bf1 into apache:main Oct 15, 2025
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

parquet-variant parquet-variant* crates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Variant] Make VariantArray iterable [Variant] Remove potential panics when probing VariantArray

4 participants