@@ -160,6 +160,8 @@ impl StructVector {
160160 }
161161}
162162
163+ impl Eq for StructVector { }
164+
163165impl VectorOps for StructVector {
164166 type Mutable = StructVectorMut ;
165167 type Scalar = StructScalar ;
@@ -270,3 +272,221 @@ impl VectorOps for StructVector {
270272 }
271273 }
272274}
275+
276+ #[ cfg( test) ]
277+ mod tests {
278+ use std:: sync:: Arc ;
279+
280+ use vortex_mask:: Mask ;
281+
282+ use super :: * ;
283+ use crate :: bool:: BoolVectorMut ;
284+ use crate :: null:: NullVector ;
285+ use crate :: primitive:: PVectorMut ;
286+
287+ #[ test]
288+ fn test_struct_vector_eq_identical ( ) {
289+ // Two identical struct vectors should be equal.
290+ let v1 = StructVector :: new (
291+ Arc :: new ( Box :: new ( [
292+ NullVector :: new ( 3 ) . into ( ) ,
293+ BoolVectorMut :: from_iter ( [ true , false , true ] )
294+ . freeze ( )
295+ . into ( ) ,
296+ PVectorMut :: < i32 > :: from_iter ( [ 10 , 20 , 30 ] ) . freeze ( ) . into ( ) ,
297+ ] ) ) ,
298+ Mask :: AllTrue ( 3 ) ,
299+ ) ;
300+
301+ let v2 = StructVector :: new (
302+ Arc :: new ( Box :: new ( [
303+ NullVector :: new ( 3 ) . into ( ) ,
304+ BoolVectorMut :: from_iter ( [ true , false , true ] )
305+ . freeze ( )
306+ . into ( ) ,
307+ PVectorMut :: < i32 > :: from_iter ( [ 10 , 20 , 30 ] ) . freeze ( ) . into ( ) ,
308+ ] ) ) ,
309+ Mask :: AllTrue ( 3 ) ,
310+ ) ;
311+
312+ assert_eq ! ( v1, v2) ;
313+ }
314+
315+ #[ test]
316+ fn test_struct_vector_eq_different_length ( ) {
317+ // Struct vectors with different lengths should not be equal.
318+ let v1 = StructVector :: new (
319+ Arc :: new ( Box :: new ( [ PVectorMut :: < i32 > :: from_iter ( [ 10 , 20 , 30 ] )
320+ . freeze ( )
321+ . into ( ) ] ) ) ,
322+ Mask :: AllTrue ( 3 ) ,
323+ ) ;
324+
325+ let v2 = StructVector :: new (
326+ Arc :: new ( Box :: new ( [ PVectorMut :: < i32 > :: from_iter ( [ 10 , 20 ] )
327+ . freeze ( )
328+ . into ( ) ] ) ) ,
329+ Mask :: AllTrue ( 2 ) ,
330+ ) ;
331+
332+ assert_ne ! ( v1, v2) ;
333+ }
334+
335+ #[ test]
336+ fn test_struct_vector_eq_different_field_count ( ) {
337+ // Struct vectors with different number of fields should not be equal.
338+ let v1 = StructVector :: new (
339+ Arc :: new ( Box :: new ( [
340+ PVectorMut :: < i32 > :: from_iter ( [ 10 , 20 , 30 ] ) . freeze ( ) . into ( ) ,
341+ BoolVectorMut :: from_iter ( [ true , false , true ] )
342+ . freeze ( )
343+ . into ( ) ,
344+ ] ) ) ,
345+ Mask :: AllTrue ( 3 ) ,
346+ ) ;
347+
348+ let v2 = StructVector :: new (
349+ Arc :: new ( Box :: new ( [ PVectorMut :: < i32 > :: from_iter ( [ 10 , 20 , 30 ] )
350+ . freeze ( )
351+ . into ( ) ] ) ) ,
352+ Mask :: AllTrue ( 3 ) ,
353+ ) ;
354+
355+ assert_ne ! ( v1, v2) ;
356+ }
357+
358+ #[ test]
359+ fn test_struct_vector_eq_different_validity ( ) {
360+ // Struct vectors with different validity patterns should not be equal.
361+ let v1 = StructVector :: new (
362+ Arc :: new ( Box :: new ( [ PVectorMut :: < i32 > :: from_iter ( [ 10 , 20 , 30 ] )
363+ . freeze ( )
364+ . into ( ) ] ) ) ,
365+ Mask :: AllTrue ( 3 ) ,
366+ ) ;
367+
368+ let v2 = StructVector :: new (
369+ Arc :: new ( Box :: new ( [ PVectorMut :: < i32 > :: from_iter ( [ 10 , 20 , 30 ] )
370+ . freeze ( )
371+ . into ( ) ] ) ) ,
372+ Mask :: from_iter ( [ true , false , true ] ) ,
373+ ) ;
374+
375+ assert_ne ! ( v1, v2) ;
376+ }
377+
378+ #[ test]
379+ fn test_struct_vector_eq_different_field_values ( ) {
380+ // Struct vectors with different field values should not be equal.
381+ let v1 = StructVector :: new (
382+ Arc :: new ( Box :: new ( [ PVectorMut :: < i32 > :: from_iter ( [ 10 , 20 , 30 ] )
383+ . freeze ( )
384+ . into ( ) ] ) ) ,
385+ Mask :: AllTrue ( 3 ) ,
386+ ) ;
387+
388+ let v2 = StructVector :: new (
389+ Arc :: new ( Box :: new ( [ PVectorMut :: < i32 > :: from_iter ( [ 10 , 99 , 30 ] )
390+ . freeze ( )
391+ . into ( ) ] ) ) ,
392+ Mask :: AllTrue ( 3 ) ,
393+ ) ;
394+
395+ assert_ne ! ( v1, v2) ;
396+ }
397+
398+ #[ test]
399+ fn test_struct_vector_eq_ignores_invalid_positions ( ) {
400+ // Two struct vectors with different values at invalid positions should be equal
401+ // as long as they have the same validity pattern and same values at valid positions.
402+ //
403+ // validity = [true, false, true] means position 1 is invalid
404+ let validity = Mask :: from_iter ( [ true , false , true ] ) ;
405+
406+ let v1 = StructVector :: new (
407+ Arc :: new ( Box :: new ( [ PVectorMut :: < i32 > :: from_iter ( [ 10 , 20 , 30 ] )
408+ . freeze ( )
409+ . into ( ) ] ) ) ,
410+ validity. clone ( ) ,
411+ ) ;
412+
413+ // Different value at position 1 (which is invalid)
414+ let v2 = StructVector :: new (
415+ Arc :: new ( Box :: new ( [ PVectorMut :: < i32 > :: from_iter ( [ 10 , 99 , 30 ] )
416+ . freeze ( )
417+ . into ( ) ] ) ) ,
418+ validity,
419+ ) ;
420+
421+ assert_eq ! ( v1, v2) ;
422+ }
423+
424+ #[ test]
425+ fn test_struct_vector_eq_combined_mask_applied ( ) {
426+ // Test that the combined mask (self.validity AND other.validity) is applied.
427+ // Both vectors have the same validity, so the combined mask equals that validity.
428+ //
429+ // validity = [true, false, true, false, true] means positions 1,3 are invalid
430+ let validity = Mask :: from_iter ( [ true , false , true , false , true ] ) ;
431+
432+ let v1 = StructVector :: new (
433+ Arc :: new ( Box :: new ( [
434+ PVectorMut :: < i32 > :: from_iter ( [ 1 , 2 , 3 , 4 , 5 ] )
435+ . freeze ( )
436+ . into ( ) ,
437+ BoolVectorMut :: from_iter ( [ true , true , true , true , true ] )
438+ . freeze ( )
439+ . into ( ) ,
440+ ] ) ) ,
441+ validity. clone ( ) ,
442+ ) ;
443+
444+ // Different values at invalid positions (1 and 3)
445+ let v2 = StructVector :: new (
446+ Arc :: new ( Box :: new ( [
447+ PVectorMut :: < i32 > :: from_iter ( [ 1 , 999 , 3 , 888 , 5 ] )
448+ . freeze ( )
449+ . into ( ) ,
450+ BoolVectorMut :: from_iter ( [ true , false , true , false , true ] )
451+ . freeze ( )
452+ . into ( ) ,
453+ ] ) ) ,
454+ validity,
455+ ) ;
456+
457+ assert_eq ! ( v1, v2) ;
458+ }
459+
460+ #[ test]
461+ fn test_struct_vector_eq_nested ( ) {
462+ // Test equality with nested struct vectors.
463+ let inner1 = StructVector :: new (
464+ Arc :: new ( Box :: new ( [ BoolVectorMut :: from_iter ( [ true , false , true ] )
465+ . freeze ( )
466+ . into ( ) ] ) ) ,
467+ Mask :: AllTrue ( 3 ) ,
468+ ) ;
469+
470+ let inner2 = StructVector :: new (
471+ Arc :: new ( Box :: new ( [ BoolVectorMut :: from_iter ( [ true , false , true ] )
472+ . freeze ( )
473+ . into ( ) ] ) ) ,
474+ Mask :: AllTrue ( 3 ) ,
475+ ) ;
476+
477+ let v1 = StructVector :: new ( Arc :: new ( Box :: new ( [ inner1. into ( ) ] ) ) , Mask :: AllTrue ( 3 ) ) ;
478+
479+ let v2 = StructVector :: new ( Arc :: new ( Box :: new ( [ inner2. into ( ) ] ) ) , Mask :: AllTrue ( 3 ) ) ;
480+
481+ assert_eq ! ( v1, v2) ;
482+ }
483+
484+ #[ test]
485+ fn test_struct_vector_eq_empty ( ) {
486+ // Two empty struct vectors should be equal.
487+ let v1 = StructVector :: new ( Arc :: new ( Box :: new ( [ ] ) ) , Mask :: AllTrue ( 0 ) ) ;
488+ let v2 = StructVector :: new ( Arc :: new ( Box :: new ( [ ] ) ) , Mask :: AllTrue ( 0 ) ) ;
489+
490+ assert_eq ! ( v1, v2) ;
491+ }
492+ }
0 commit comments