Skip to content

Commit 5a1b7e4

Browse files
authored
Merge branch 'main' into avro-reader-schema-store
2 parents dc56c70 + 5dd3463 commit 5a1b7e4

File tree

30 files changed

+2132
-285
lines changed

30 files changed

+2132
-285
lines changed

.github/workflows/arrow.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,10 @@ jobs:
6868
- name: Test arrow-schema
6969
run: cargo test -p arrow-schema --all-features
7070
- name: Test arrow-array
71-
run: cargo test -p arrow-array --all-features
71+
run: |
72+
cargo test -p arrow-array --all-features
73+
# Disable feature `force_validate`
74+
cargo test -p arrow-array --features=ffi
7275
- name: Test arrow-select
7376
run: cargo test -p arrow-select --all-features
7477
- name: Test arrow-cast

CHANGELOG-old.md

Lines changed: 320 additions & 0 deletions
Large diffs are not rendered by default.

CHANGELOG.md

Lines changed: 225 additions & 121 deletions
Large diffs are not rendered by default.

CONTRIBUTING.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,7 @@ You can also use rust's official docker image:
8989
docker run --rm -v $(pwd):/arrow-rs -it rust /bin/bash -c "cd /arrow-rs && rustup component add rustfmt && cargo build"
9090
```
9191

92-
The command above assumes that are in the root directory of the project, not in the same
93-
directory as this README.md.
92+
The command above assumes that are in the root directory of the project.
9493

9594
You can also compile specific workspaces:
9695

Cargo.toml

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ exclude = [
6767
]
6868

6969
[workspace.package]
70-
version = "55.2.0"
70+
version = "56.0.0"
7171
homepage = "https://github.com/apache/arrow-rs"
7272
repository = "https://github.com/apache/arrow-rs"
7373
authors = ["Apache Arrow <dev@arrow.apache.org>"]
@@ -84,22 +84,22 @@ edition = "2021"
8484
rust-version = "1.84"
8585

8686
[workspace.dependencies]
87-
arrow = { version = "55.2.0", path = "./arrow", default-features = false }
88-
arrow-arith = { version = "55.2.0", path = "./arrow-arith" }
89-
arrow-array = { version = "55.2.0", path = "./arrow-array" }
90-
arrow-buffer = { version = "55.2.0", path = "./arrow-buffer" }
91-
arrow-cast = { version = "55.2.0", path = "./arrow-cast" }
92-
arrow-csv = { version = "55.2.0", path = "./arrow-csv" }
93-
arrow-data = { version = "55.2.0", path = "./arrow-data" }
94-
arrow-ipc = { version = "55.2.0", path = "./arrow-ipc" }
95-
arrow-json = { version = "55.2.0", path = "./arrow-json" }
96-
arrow-ord = { version = "55.2.0", path = "./arrow-ord" }
97-
arrow-pyarrow = { version = "55.2.0", path = "./arrow-pyarrow" }
98-
arrow-row = { version = "55.2.0", path = "./arrow-row" }
99-
arrow-schema = { version = "55.2.0", path = "./arrow-schema" }
100-
arrow-select = { version = "55.2.0", path = "./arrow-select" }
101-
arrow-string = { version = "55.2.0", path = "./arrow-string" }
102-
parquet = { version = "55.2.0", path = "./parquet", default-features = false }
87+
arrow = { version = "56.0.0", path = "./arrow", default-features = false }
88+
arrow-arith = { version = "56.0.0", path = "./arrow-arith" }
89+
arrow-array = { version = "56.0.0", path = "./arrow-array" }
90+
arrow-buffer = { version = "56.0.0", path = "./arrow-buffer" }
91+
arrow-cast = { version = "56.0.0", path = "./arrow-cast" }
92+
arrow-csv = { version = "56.0.0", path = "./arrow-csv" }
93+
arrow-data = { version = "56.0.0", path = "./arrow-data" }
94+
arrow-ipc = { version = "56.0.0", path = "./arrow-ipc" }
95+
arrow-json = { version = "56.0.0", path = "./arrow-json" }
96+
arrow-ord = { version = "56.0.0", path = "./arrow-ord" }
97+
arrow-pyarrow = { version = "56.0.0", path = "./arrow-pyarrow" }
98+
arrow-row = { version = "56.0.0", path = "./arrow-row" }
99+
arrow-schema = { version = "56.0.0", path = "./arrow-schema" }
100+
arrow-select = { version = "56.0.0", path = "./arrow-select" }
101+
arrow-string = { version = "56.0.0", path = "./arrow-string" }
102+
parquet = { version = "56.0.0", path = "./parquet", default-features = false }
103103

104104
# These crates have not yet been released and thus do not use the workspace version
105105
parquet-variant = { version = "0.1.0", path = "./parquet-variant" }

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ The deprecated version is the next version which will be released (please
108108
consult the list above). To mark the API as deprecated, use the
109109
`#[deprecated(since = "...", note = "...")]` attribute.
110110

111-
Foe example
111+
For example
112112

113113
```rust
114114
#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]

arrow-array/src/ffi.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,17 @@ impl ImportedArrowArray<'_> {
408408
.map(|index| {
409409
let len = self.buffer_len(index, variadic_buffer_lens, &self.data_type)?;
410410
match unsafe { create_buffer(self.owner.clone(), self.array, index, len) } {
411-
Some(buf) => Ok(buf),
411+
Some(buf) => {
412+
// External libraries may use a dangling pointer for a buffer with length 0.
413+
// We respect the array length specified in the C Data Interface. Actually,
414+
// if the length is incorrect, we cannot create a correct buffer even if
415+
// the pointer is valid.
416+
if buf.is_empty() {
417+
Ok(MutableBuffer::new(0).into())
418+
} else {
419+
Ok(buf)
420+
}
421+
}
412422
None if len == 0 => {
413423
// Null data buffer, which Rust doesn't allow. So create
414424
// an empty buffer.
@@ -1296,9 +1306,15 @@ mod tests_to_then_from_ffi {
12961306

12971307
#[cfg(test)]
12981308
mod tests_from_ffi {
1309+
#[cfg(not(feature = "force_validate"))]
1310+
use std::ptr::NonNull;
12991311
use std::sync::Arc;
13001312

1313+
#[cfg(feature = "force_validate")]
13011314
use arrow_buffer::{bit_util, buffer::Buffer};
1315+
#[cfg(not(feature = "force_validate"))]
1316+
use arrow_buffer::{bit_util, buffer::Buffer, ScalarBuffer};
1317+
13021318
use arrow_data::transform::MutableArrayData;
13031319
use arrow_data::ArrayData;
13041320
use arrow_schema::{DataType, Field};
@@ -1660,6 +1676,25 @@ mod tests_from_ffi {
16601676
}
16611677
}
16621678

1679+
#[test]
1680+
#[cfg(not(feature = "force_validate"))]
1681+
fn test_utf8_view_ffi_from_dangling_pointer() {
1682+
let empty = GenericByteViewBuilder::<StringViewType>::new().finish();
1683+
let buffers = empty.data_buffers().to_vec();
1684+
let nulls = empty.nulls().cloned();
1685+
1686+
// Create a dangling pointer to a view buffer with zero length.
1687+
let alloc = Arc::new(1);
1688+
let buffer = unsafe { Buffer::from_custom_allocation(NonNull::<u8>::dangling(), 0, alloc) };
1689+
let views = unsafe { ScalarBuffer::new_unchecked(buffer) };
1690+
1691+
let str_view: GenericByteViewArray<StringViewType> =
1692+
unsafe { GenericByteViewArray::new_unchecked(views, buffers, nulls) };
1693+
let imported = roundtrip_byte_view_array(str_view);
1694+
assert_eq!(imported.len(), 0);
1695+
assert_eq!(&imported, &empty);
1696+
}
1697+
16631698
#[test]
16641699
fn test_round_trip_byte_view() {
16651700
fn test_case<T>()

arrow-avro/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ strum_macros = "0.27"
5959
uuid = "1.17"
6060
indexmap = "2.10"
6161

62+
6263
[dev-dependencies]
6364
arrow-data = { workspace = true }
6465
rand = { version = "0.9.1", default-features = false, features = [

arrow-avro/src/reader/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,12 @@
3434
//! # use std::fs::File;
3535
//! # use std::io::BufReader;
3636
//! # use arrow_avro::reader::ReaderBuilder;
37-
//!
38-
//! let file = File::open("../testing/data/avro/alltypes_plain.avro").unwrap();
37+
//! # let path = "avro/alltypes_plain.avro";
38+
//! # let path = match std::env::var("ARROW_TEST_DATA") {
39+
//! # Ok(dir) => format!("{dir}/{path}"),
40+
//! # Err(_) => format!("../testing/data/{path}")
41+
//! # };
42+
//! let file = File::open(path).unwrap();
3943
//! let mut avro = ReaderBuilder::new().build(BufReader::new(file)).unwrap();
4044
//! let batch = avro.next().unwrap();
4145
//! ```

arrow-buffer/src/bigint/mod.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,20 @@ impl ToPrimitive for i256 {
821821
}
822822
}
823823

824+
fn to_f64(&self) -> Option<f64> {
825+
let mag = if let Some(u) = self.checked_abs() {
826+
let (low, high) = u.to_parts();
827+
(high as f64) * 2_f64.powi(128) + (low as f64)
828+
} else {
829+
// self == MIN
830+
2_f64.powi(255)
831+
};
832+
if *self < i256::ZERO {
833+
Some(-mag)
834+
} else {
835+
Some(mag)
836+
}
837+
}
824838
fn to_u64(&self) -> Option<u64> {
825839
let as_i128 = self.low as i128;
826840

@@ -1264,4 +1278,29 @@ mod tests {
12641278
}
12651279
}
12661280
}
1281+
1282+
#[test]
1283+
fn test_decimal256_to_f64_typical_values() {
1284+
let v = i256::from_i128(42_i128);
1285+
assert_eq!(v.to_f64().unwrap(), 42.0);
1286+
1287+
let v = i256::from_i128(-123456789012345678i128);
1288+
assert_eq!(v.to_f64().unwrap(), -123456789012345678.0);
1289+
}
1290+
1291+
#[test]
1292+
fn test_decimal256_to_f64_large_positive_value() {
1293+
let max_f = f64::MAX;
1294+
let big = i256::from_f64(max_f * 2.0).unwrap_or(i256::MAX);
1295+
let out = big.to_f64().unwrap();
1296+
assert!(out.is_finite() && out.is_sign_positive());
1297+
}
1298+
1299+
#[test]
1300+
fn test_decimal256_to_f64_large_negative_value() {
1301+
let max_f = f64::MAX;
1302+
let big_neg = i256::from_f64(-(max_f * 2.0)).unwrap_or(i256::MIN);
1303+
let out = big_neg.to_f64().unwrap();
1304+
assert!(out.is_finite() && out.is_sign_negative());
1305+
}
12671306
}

0 commit comments

Comments
 (0)