Uploaded image for project: 'Apache Arrow'
  1. Apache Arrow
  2. ARROW-11394

[Rust] Slice + Concat incorrect for structs

    XMLWordPrintableJSON

Details

    Description

      If you slice an array and then use it with concat you get different behaviors when using a primitive array (Float64 in the examples) or a struct array.

      In the case of a float, the result is what I'd expect – it concatenates the elements from the slice.

      In the case of a struct, it is a bit surprising – the result has the length of the slice, but starts at the beginning of the original array.

      // #[test]
      fn test_repro() {
          // Create float and struct array.
          let float_array: ArrayRef = Arc::new(Float64Array::from(vec![1.0, 2.0, 3.0, 4.0]));
          let struct_array = Arc::new(StructArray::from(vec![(
              Field::new("field", DataType::Float64, true),
              float_array.clone(),
          )]));
      
          // Slice the float array and verify result is [3.0, 4.0]
          let float_array_slice_ref = float_array.slice(2, 2);
          let float_array_slice = float_array_slice_ref
              .as_any()
              .downcast_ref::<PrimitiveArray<Float64Type>>()
              .unwrap();
          assert_eq!(float_array_slice, &Float64Array::from(vec![3.0, 4.0]));
      
          // Slice the struct array and verify result is [3.0, 4.0]
          let struct_array_slice_ref = struct_array.slice(2, 2);
          let struct_array_slice = struct_array_slice_ref
              .as_any()
              .downcast_ref::<StructArray>()
              .unwrap();
          let struct_array_slice_floats = struct_array_slice
              .column(0)
              .as_any()
              .downcast_ref::<PrimitiveArray<Float64Type>>()
              .unwrap();
          assert_eq!(
              struct_array_slice_floats,
              &Float64Array::from(vec![3.0, 4.0])
          );
      
          // Concat the float array, and verify the result is still [3.0, 4.0].
          let concat_float_array_ref =
              arrow::compute::kernels::concat::concat(&[float_array_slice]).unwrap();
          let concat_float_array = concat_float_array_ref
              .as_any()
              .downcast_ref::<PrimitiveArray<Float64Type>>()
              .unwrap();
          assert_eq!(concat_float_array, &Float64Array::from(vec![3.0, 4.0]));
      
          // Concat the struct array and expect it to match the float array [3.0, 4.0].
          let concat_struct_array_ref =
              arrow::compute::kernels::concat::concat(&[struct_array_slice]).unwrap();
          let concat_struct_array = concat_struct_array_ref
              .as_any()
              .downcast_ref::<StructArray>()
              .unwrap();
          let concat_struct_array_floats = concat_struct_array
              .column(0)
              .as_any()
              .downcast_ref::<PrimitiveArray<Float64Type>>()
              .unwrap();
          // This is what is actually returned
          assert_eq!(
              concat_struct_array_floats,
              &Float64Array::from(vec![1.0, 2.0])
          );
      
          // This is what I'd expect, but fails:
          assert_eq!(
              concat_struct_array_floats,
              &Float64Array::from(vec![3.0, 4.0])
          );
      }

      Attachments

        Issue Links

          Activity

            People

              bchambers Ben Chambers
              bchambers Ben Chambers
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0h
                  0h
                  Logged:
                  Time Spent - 2h 40m
                  2h 40m