@@ -93,6 +93,10 @@ pub trait SparkUnsafeObject {
9393 let addr = self . get_element_offset ( index, 1 ) ;
9494 // SAFETY: addr points to valid element data within the UnsafeRow/UnsafeArray region.
9595 // The caller ensures index is within bounds.
96+ debug_assert ! (
97+ !addr. is_null( ) ,
98+ "get_boolean: null pointer at index {index}"
99+ ) ;
96100 unsafe { * addr != 0 }
97101 }
98102
@@ -101,6 +105,7 @@ pub trait SparkUnsafeObject {
101105 fn get_byte ( & self , index : usize ) -> i8 {
102106 let addr = self . get_element_offset ( index, 1 ) ;
103107 // SAFETY: addr points to valid element data (1 byte) within the row/array region.
108+ debug_assert ! ( !addr. is_null( ) , "get_byte: null pointer at index {index}" ) ;
104109 let slice: & [ u8 ] = unsafe { std:: slice:: from_raw_parts ( addr, 1 ) } ;
105110 i8:: from_le_bytes ( slice. try_into ( ) . unwrap ( ) )
106111 }
@@ -110,6 +115,7 @@ pub trait SparkUnsafeObject {
110115 fn get_short ( & self , index : usize ) -> i16 {
111116 let addr = self . get_element_offset ( index, 2 ) ;
112117 // SAFETY: addr points to valid element data (2 bytes) within the row/array region.
118+ debug_assert ! ( !addr. is_null( ) , "get_short: null pointer at index {index}" ) ;
113119 let slice: & [ u8 ] = unsafe { std:: slice:: from_raw_parts ( addr, 2 ) } ;
114120 i16:: from_le_bytes ( slice. try_into ( ) . unwrap ( ) )
115121 }
@@ -119,6 +125,7 @@ pub trait SparkUnsafeObject {
119125 fn get_int ( & self , index : usize ) -> i32 {
120126 let addr = self . get_element_offset ( index, 4 ) ;
121127 // SAFETY: addr points to valid element data (4 bytes) within the row/array region.
128+ debug_assert ! ( !addr. is_null( ) , "get_int: null pointer at index {index}" ) ;
122129 let slice: & [ u8 ] = unsafe { std:: slice:: from_raw_parts ( addr, 4 ) } ;
123130 i32:: from_le_bytes ( slice. try_into ( ) . unwrap ( ) )
124131 }
@@ -128,6 +135,7 @@ pub trait SparkUnsafeObject {
128135 fn get_long ( & self , index : usize ) -> i64 {
129136 let addr = self . get_element_offset ( index, 8 ) ;
130137 // SAFETY: addr points to valid element data (8 bytes) within the row/array region.
138+ debug_assert ! ( !addr. is_null( ) , "get_long: null pointer at index {index}" ) ;
131139 let slice: & [ u8 ] = unsafe { std:: slice:: from_raw_parts ( addr, 8 ) } ;
132140 i64:: from_le_bytes ( slice. try_into ( ) . unwrap ( ) )
133141 }
@@ -137,6 +145,7 @@ pub trait SparkUnsafeObject {
137145 fn get_float ( & self , index : usize ) -> f32 {
138146 let addr = self . get_element_offset ( index, 4 ) ;
139147 // SAFETY: addr points to valid element data (4 bytes) within the row/array region.
148+ debug_assert ! ( !addr. is_null( ) , "get_float: null pointer at index {index}" ) ;
140149 let slice: & [ u8 ] = unsafe { std:: slice:: from_raw_parts ( addr, 4 ) } ;
141150 f32:: from_le_bytes ( slice. try_into ( ) . unwrap ( ) )
142151 }
@@ -146,6 +155,7 @@ pub trait SparkUnsafeObject {
146155 fn get_double ( & self , index : usize ) -> f64 {
147156 let addr = self . get_element_offset ( index, 8 ) ;
148157 // SAFETY: addr points to valid element data (8 bytes) within the row/array region.
158+ debug_assert ! ( !addr. is_null( ) , "get_double: null pointer at index {index}" ) ;
149159 let slice: & [ u8 ] = unsafe { std:: slice:: from_raw_parts ( addr, 8 ) } ;
150160 f64:: from_le_bytes ( slice. try_into ( ) . unwrap ( ) )
151161 }
@@ -156,6 +166,11 @@ pub trait SparkUnsafeObject {
156166 let addr = self . get_row_addr ( ) + offset as i64 ;
157167 // SAFETY: addr points to valid UTF-8 string data within the variable-length region.
158168 // Offset and length are read from the fixed-length portion of the row/array.
169+ debug_assert ! ( addr != 0 , "get_string: null address at index {index}" ) ;
170+ debug_assert ! (
171+ len >= 0 ,
172+ "get_string: negative length {len} at index {index}"
173+ ) ;
159174 let slice: & [ u8 ] = unsafe { std:: slice:: from_raw_parts ( addr as * const u8 , len as usize ) } ;
160175
161176 from_utf8 ( slice) . unwrap ( )
@@ -167,6 +182,11 @@ pub trait SparkUnsafeObject {
167182 let addr = self . get_row_addr ( ) + offset as i64 ;
168183 // SAFETY: addr points to valid binary data within the variable-length region.
169184 // Offset and length are read from the fixed-length portion of the row/array.
185+ debug_assert ! ( addr != 0 , "get_binary: null address at index {index}" ) ;
186+ debug_assert ! (
187+ len >= 0 ,
188+ "get_binary: negative length {len} at index {index}"
189+ ) ;
170190 unsafe { std:: slice:: from_raw_parts ( addr as * const u8 , len as usize ) }
171191 }
172192
@@ -175,6 +195,7 @@ pub trait SparkUnsafeObject {
175195 fn get_date ( & self , index : usize ) -> i32 {
176196 let addr = self . get_element_offset ( index, 4 ) ;
177197 // SAFETY: addr points to valid element data (4 bytes) within the row/array region.
198+ debug_assert ! ( !addr. is_null( ) , "get_date: null pointer at index {index}" ) ;
178199 let slice: & [ u8 ] = unsafe { std:: slice:: from_raw_parts ( addr, 4 ) } ;
179200 i32:: from_le_bytes ( slice. try_into ( ) . unwrap ( ) )
180201 }
@@ -184,6 +205,10 @@ pub trait SparkUnsafeObject {
184205 fn get_timestamp ( & self , index : usize ) -> i64 {
185206 let addr = self . get_element_offset ( index, 8 ) ;
186207 // SAFETY: addr points to valid element data (8 bytes) within the row/array region.
208+ debug_assert ! (
209+ !addr. is_null( ) ,
210+ "get_timestamp: null pointer at index {index}"
211+ ) ;
187212 let slice: & [ u8 ] = unsafe { std:: slice:: from_raw_parts ( addr, 8 ) } ;
188213 i64:: from_le_bytes ( slice. try_into ( ) . unwrap ( ) )
189214 }
@@ -296,6 +321,7 @@ impl SparkUnsafeRow {
296321 // SAFETY: row_addr points to valid Spark UnsafeRow data with at least
297322 // ceil(num_fields/64) * 8 bytes of null bitset. The caller ensures index < num_fields.
298323 // word_offset is within the bitset region since (index >> 6) << 3 < bitset size.
324+ debug_assert ! ( self . row_addr != -1 , "is_null_at: row not initialized" ) ;
299325 unsafe {
300326 let mask: i64 = 1i64 << ( index & 0x3f ) ;
301327 let word_offset = ( self . row_addr + ( ( ( index >> 6 ) as i64 ) << 3 ) ) as * const i64 ;
@@ -310,6 +336,7 @@ impl SparkUnsafeRow {
310336 // ceil(num_fields/64) * 8 bytes of null bitset. The caller ensures index < num_fields.
311337 // word_offset is within the bitset region since (index >> 6) << 3 < bitset size.
312338 // Writing is safe because we have mutable access and the memory is owned by the JVM.
339+ debug_assert ! ( self . row_addr != -1 , "set_not_null_at: row not initialized" ) ;
313340 unsafe {
314341 let mask: i64 = 1i64 << ( index & 0x3f ) ;
315342 let word_offset = ( self . row_addr + ( ( ( index >> 6 ) as i64 ) << 3 ) ) as * mut i64 ;
0 commit comments