This is an automated email from the ASF dual-hosted git repository. github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-12005-cd34df88ea2ca16b6e6482adf6b7f3ca01e23cf3 in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
commit bf0cde345b14e5abdf3e8abb57f55d43da48b49f Author: Kosta Tarasov <[email protected]> AuthorDate: Fri Oct 30 20:28:55 2026 +0000 [Variant] Move `VariantType` from `parquet-variant-compute` to `parquet-variant` (#12005) # Which issue does this PR close? - Closes #11952. # Rationale for this change Using the `arrow.parquet.variant` extension type currently requires depending on `parquet-variant-compute`, which pulls in the full `arrow` crate and `parquet-variant-json`. Schema-only consumers such as `datafusion-common` and `datafusion-expr` (apache/datafusion#26822) only need the type itself, which depends on nothing beyond `arrow-schema`. # What changes are included in this PR? `VariantType` moves unchanged from `parquet-variant-compute/src/variant_array.rs` to a new `parquet-variant/src/extension.rs` and is exported as `parquet_variant::VariantType`. `parquet-variant-compute` re-exports it, so `parquet_variant_compute::VariantType` and `parquet::variant::VariantType` keep working and refer to the same type. # Are these changes tested? Yes. Existing uses through the old paths (the `VariantArray` doctests, `variant_get`, and the `parquet` Variant schema tests) are unchanged and still pass. A new unit test in `parquet-variant` covers the type on its own: a struct field accepts the extension and a non-struct field is rejected with the existing error message. # Are there any significant user-facing changes? `VariantType` is now also available from `parquet-variant`. The existing import path is kept, so this is not a breaking change. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <[email protected]> --- parquet-variant-compute/src/lib.rs | 3 +- parquet-variant-compute/src/variant_array.rs | 48 +-------------- parquet-variant/src/extension.rs | 90 ++++++++++++++++++++++++++++ parquet-variant/src/lib.rs | 2 + 4 files changed, 96 insertions(+), 47 deletions(-) diff --git a/parquet-variant-compute/src/lib.rs b/parquet-variant-compute/src/lib.rs index bb80b4febf..c2963867be 100644 --- a/parquet-variant-compute/src/lib.rs +++ b/parquet-variant-compute/src/lib.rs @@ -58,7 +58,8 @@ mod variant_array_builder; mod variant_get; mod variant_to_arrow; -pub use variant_array::{ShreddingState, VariantArray, VariantArrayIter, VariantType}; +pub use parquet_variant::VariantType; +pub use variant_array::{ShreddingState, VariantArray, VariantArrayIter}; pub use variant_array_builder::{VariantArrayBuilder, VariantValueArrayBuilder}; pub use cast_to_variant::{cast_to_variant, cast_to_variant_with_options}; diff --git a/parquet-variant-compute/src/variant_array.rs b/parquet-variant-compute/src/variant_array.rs index 8327421f0b..ebca96bccc 100644 --- a/parquet-variant-compute/src/variant_array.rs +++ b/parquet-variant-compute/src/variant_array.rs @@ -34,11 +34,12 @@ use arrow::datatypes::{ TimestampMicrosecondType, TimestampNanosecondType, }; use arrow::error::Result; -use arrow_schema::extension::{ExtensionType, Uuid as UuidExtension}; +use arrow_schema::extension::Uuid as UuidExtension; use arrow_schema::{ArrowError, DataType, Field, FieldRef, TimeUnit}; use chrono::{DateTime, NaiveTime}; use parquet_variant::{ Uuid, Variant, VariantDecimal4, VariantDecimal8, VariantDecimal16, VariantDecimalType as _, + VariantType, }; use std::borrow::Cow; @@ -123,51 +124,6 @@ fn validate_metadata_array(array: &dyn Array) -> Result<()> { } } -/// Arrow Variant [`ExtensionType`]. -/// -/// Represents the canonical Arrow Extension Type for storing variants. -/// See [`VariantArray`] for more examples of using this extension type. -pub struct VariantType; - -impl ExtensionType for VariantType { - const NAME: &'static str = "arrow.parquet.variant"; - - // Variants extension metadata is an empty string - // <https://github.com/apache/arrow/blob/d803afcc43f5d132506318fd9e162d33b2c3d4cd/docs/source/format/CanonicalExtensions.rst?plain=1#L473> - type Metadata = &'static str; - - fn metadata(&self) -> &Self::Metadata { - &"" - } - - fn serialize_metadata(&self) -> Option<String> { - Some(String::new()) - } - - fn deserialize_metadata(_metadata: Option<&str>) -> Result<Self::Metadata> { - Ok("") - } - - fn supports_data_type(&self, data_type: &DataType) -> Result<()> { - if matches!(data_type, DataType::Struct(_)) { - Ok(()) - } else { - Err(ArrowError::InvalidArgumentError(format!( - "VariantType only supports StructArray, got {data_type}" - ))) - } - } - - fn try_new(data_type: &DataType, _metadata: Self::Metadata) -> Result<Self> { - Self.supports_data_type(data_type)?; - Ok(Self) - } - - fn validate(data_type: &DataType, _metadata: Self::Metadata) -> Result<()> { - Self.supports_data_type(data_type) - } -} - /// An array of Parquet [`Variant`] values /// /// A [`VariantArray`] wraps an Arrow [`StructArray`] that stores the underlying diff --git a/parquet-variant/src/extension.rs b/parquet-variant/src/extension.rs new file mode 100644 index 0000000000..3cca1b9f3a --- /dev/null +++ b/parquet-variant/src/extension.rs @@ -0,0 +1,90 @@ +// 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 +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +//! [`VariantType`] Arrow extension type + +use arrow_schema::extension::ExtensionType; +use arrow_schema::{ArrowError, DataType}; + +/// Arrow Variant [`ExtensionType`]. +/// +/// Represents the canonical Arrow Extension Type for storing variants. +/// See [`VariantArray`] in the `parquet-variant-compute` crate for more examples +/// of using this extension type. +/// +/// [`VariantArray`]: https://docs.rs/parquet-variant-compute/latest/parquet_variant_compute/struct.VariantArray.html +pub struct VariantType; + +impl ExtensionType for VariantType { + const NAME: &'static str = "arrow.parquet.variant"; + + // Variants extension metadata is an empty string + // <https://github.com/apache/arrow/blob/d803afcc43f5d132506318fd9e162d33b2c3d4cd/docs/source/format/CanonicalExtensions.rst?plain=1#L473> + type Metadata = &'static str; + + fn metadata(&self) -> &Self::Metadata { + &"" + } + + fn serialize_metadata(&self) -> Option<String> { + Some(String::new()) + } + + fn deserialize_metadata(_metadata: Option<&str>) -> Result<Self::Metadata, ArrowError> { + Ok("") + } + + fn supports_data_type(&self, data_type: &DataType) -> Result<(), ArrowError> { + if matches!(data_type, DataType::Struct(_)) { + Ok(()) + } else { + Err(ArrowError::InvalidArgumentError(format!( + "VariantType only supports StructArray, got {data_type}" + ))) + } + } + + fn try_new(data_type: &DataType, _metadata: Self::Metadata) -> Result<Self, ArrowError> { + Self.supports_data_type(data_type)?; + Ok(Self) + } + + fn validate(data_type: &DataType, _metadata: Self::Metadata) -> Result<(), ArrowError> { + Self.supports_data_type(data_type) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use arrow_schema::{Field, Fields}; + + #[test] + fn variant_type_requires_struct() { + let field = Field::new("v", DataType::Struct(Fields::empty()), true) + .with_extension_type(VariantType); + assert!(field.has_valid_extension_type::<VariantType>()); + + let err = Field::new("v", DataType::Binary, true) + .try_with_extension_type(VariantType) + .unwrap_err(); + assert_eq!( + err.to_string(), + "Invalid argument error: VariantType only supports StructArray, got Binary" + ); + } +} diff --git a/parquet-variant/src/lib.rs b/parquet-variant/src/lib.rs index 79a5f561b4..d7309138de 100644 --- a/parquet-variant/src/lib.rs +++ b/parquet-variant/src/lib.rs @@ -40,10 +40,12 @@ mod builder; mod decoder; +mod extension; mod path; mod utils; mod variant; pub use builder::*; +pub use extension::VariantType; pub use path::{VariantPath, VariantPathElement}; pub use variant::*;
