@@ -28,6 +28,7 @@ use std::mem;
28
28
use std:: ops:: Range ;
29
29
use std:: sync:: Arc ;
30
30
31
+ use crate :: data:: private:: UnsafeFlag ;
31
32
use crate :: { equal, validate_binary_view, validate_string_view} ;
32
33
33
34
#[ inline]
@@ -255,6 +256,10 @@ impl ArrayData {
255
256
buffers : Vec < Buffer > ,
256
257
child_data : Vec < ArrayData > ,
257
258
) -> Self {
259
+ let mut skip_validation = UnsafeFlag :: new ( ) ;
260
+ // SAFETY: caller responsible for ensuring data is valid
261
+ skip_validation. set ( true ) ;
262
+
258
263
ArrayDataBuilder {
259
264
data_type,
260
265
len,
@@ -265,8 +270,7 @@ impl ArrayData {
265
270
buffers,
266
271
child_data,
267
272
align_buffers : false ,
268
- // SAFETY: caller responsible for ensuring data is valid
269
- skip_validation : true ,
273
+ skip_validation,
270
274
}
271
275
. build ( )
272
276
. unwrap ( )
@@ -1779,6 +1783,36 @@ impl PartialEq for ArrayData {
1779
1783
}
1780
1784
}
1781
1785
1786
+ mod private {
1787
+ /// A boolean flag that cannot be mutated outside of unsafe code.
1788
+ ///
1789
+ /// Defaults to a value of false.
1790
+ ///
1791
+ /// This structure is used to enforce safety in the [`ArrayDataBuilder`]
1792
+ ///
1793
+ /// [`ArrayDataBuilder`]: super::ArrayDataBuilder
1794
+ #[ derive( Debug ) ]
1795
+ pub struct UnsafeFlag ( bool ) ;
1796
+
1797
+ impl UnsafeFlag {
1798
+ /// Creates a new `UnsafeFlag` with the value set to `false`
1799
+ #[ inline]
1800
+ pub const fn new ( ) -> Self {
1801
+ Self ( false )
1802
+ }
1803
+
1804
+ #[ inline]
1805
+ pub unsafe fn set ( & mut self , val : bool ) {
1806
+ self . 0 = val;
1807
+ }
1808
+
1809
+ #[ inline]
1810
+ pub fn get ( & self ) -> bool {
1811
+ self . 0
1812
+ }
1813
+ }
1814
+ }
1815
+
1782
1816
/// Builder for [`ArrayData`] type
1783
1817
#[ derive( Debug ) ]
1784
1818
pub struct ArrayDataBuilder {
@@ -1803,7 +1837,7 @@ pub struct ArrayDataBuilder {
1803
1837
/// This flag can only be set to true using `unsafe` APIs. However, once true
1804
1838
/// subsequent calls to `build()` may result in undefined behavior if the data
1805
1839
/// is not valid.
1806
- skip_validation : bool ,
1840
+ skip_validation : UnsafeFlag ,
1807
1841
}
1808
1842
1809
1843
impl ArrayDataBuilder {
@@ -1820,7 +1854,7 @@ impl ArrayDataBuilder {
1820
1854
buffers : vec ! [ ] ,
1821
1855
child_data : vec ! [ ] ,
1822
1856
align_buffers : false ,
1823
- skip_validation : false ,
1857
+ skip_validation : UnsafeFlag :: new ( ) ,
1824
1858
}
1825
1859
}
1826
1860
@@ -1957,7 +1991,7 @@ impl ArrayDataBuilder {
1957
1991
}
1958
1992
1959
1993
// SAFETY: `skip_validation` is only set to true using `unsafe` APIs
1960
- if !skip_validation || cfg ! ( feature = "force_validate" ) {
1994
+ if !skip_validation. get ( ) || cfg ! ( feature = "force_validate" ) {
1961
1995
data. validate_data ( ) ?;
1962
1996
}
1963
1997
Ok ( data)
@@ -2003,7 +2037,7 @@ impl ArrayDataBuilder {
2003
2037
/// If validation is skipped, the buffers must form a valid Arrow array,
2004
2038
/// otherwise undefined behavior will result
2005
2039
pub unsafe fn skip_validation ( mut self , skip_validation : bool ) -> Self {
2006
- self . skip_validation = skip_validation;
2040
+ self . skip_validation . set ( skip_validation) ;
2007
2041
self
2008
2042
}
2009
2043
}
@@ -2020,7 +2054,7 @@ impl From<ArrayData> for ArrayDataBuilder {
2020
2054
null_bit_buffer : None ,
2021
2055
null_count : None ,
2022
2056
align_buffers : false ,
2023
- skip_validation : false ,
2057
+ skip_validation : UnsafeFlag :: new ( ) ,
2024
2058
}
2025
2059
}
2026
2060
}
0 commit comments