You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by tu...@apache.org on 2023/06/30 09:44:47 UTC

[arrow-rs] branch master updated: Remove Binary Dictionary Arithmetic Support (#4407)

This is an automated email from the ASF dual-hosted git repository.

tustvold pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git


The following commit(s) were added to refs/heads/master by this push:
     new a11b975d6 Remove Binary Dictionary Arithmetic Support (#4407)
a11b975d6 is described below

commit a11b975d6081106615cee3fbdf8a89a6643271a1
Author: Raphael Taylor-Davies <17...@users.noreply.github.com>
AuthorDate: Fri Jun 30 10:44:41 2023 +0100

    Remove Binary Dictionary Arithmetic Support (#4407)
    
    * Remove Binary Dictionary Arithmetic Support
    
    * Clippy
---
 .github/workflows/arrow.yml   |    8 +-
 arrow-arith/Cargo.toml        |    4 -
 arrow-arith/src/arithmetic.rs | 1044 +++--------------------------------------
 arrow/Cargo.toml              |    5 +-
 arrow/README.md               |    1 -
 5 files changed, 71 insertions(+), 991 deletions(-)

diff --git a/.github/workflows/arrow.yml b/.github/workflows/arrow.yml
index 35e70c8f0..279e276a7 100644
--- a/.github/workflows/arrow.yml
+++ b/.github/workflows/arrow.yml
@@ -83,7 +83,7 @@ jobs:
       - name: Test arrow-ord with all features except SIMD
         run: cargo test -p arrow-ord --features dyn_cmp_dict
       - name: Test arrow-arith with all features except SIMD
-        run: cargo test -p arrow-arith --features dyn_arith_dict
+        run: cargo test -p arrow-arith
       - name: Test arrow-row with all features
         run: cargo test -p arrow-row --all-features
       - name: Test arrow-integration-test with all features
@@ -91,7 +91,7 @@ jobs:
       - name: Test arrow with default features
         run: cargo test -p arrow
       - name: Test arrow with all features apart from simd
-        run: cargo test -p arrow --features=force_validate,prettyprint,ipc_compression,ffi,dyn_cmp_dict,dyn_arith_dict,chrono-tz
+        run: cargo test -p arrow --features=force_validate,prettyprint,ipc_compression,ffi,dyn_cmp_dict,chrono-tz
       - name: Run examples
         run: |
           # Test arrow examples
@@ -209,11 +209,11 @@ jobs:
       - name: Clippy arrow-ord with all features except SIMD
         run: cargo clippy -p arrow-ord --all-targets --features dyn_cmp_dict -- -D warnings
       - name: Clippy arrow-arith with all features except SIMD
-        run: cargo clippy -p arrow-arith --all-targets --features dyn_arith_dict -- -D warnings
+        run: cargo clippy -p arrow-arith --all-targets -- -D warnings
       - name: Clippy arrow-row with all features
         run: cargo clippy -p arrow-row --all-targets --all-features -- -D warnings
       - name: Clippy arrow with all features except SIMD
-        run: cargo clippy -p arrow --features=prettyprint,csv,ipc,test_utils,ffi,ipc_compression,dyn_cmp_dict,dyn_arith_dict,chrono-tz --all-targets -- -D warnings
+        run: cargo clippy -p arrow --features=prettyprint,csv,ipc,test_utils,ffi,ipc_compression,dyn_cmp_dict,chrono-tz --all-targets -- -D warnings
       - name: Clippy arrow-integration-test with all features
         run: cargo clippy -p arrow-integration-test --all-targets --all-features -- -D warnings
       - name: Clippy arrow-integration-testing with all features
diff --git a/arrow-arith/Cargo.toml b/arrow-arith/Cargo.toml
index 4460d116b..b5ea2e3c4 100644
--- a/arrow-arith/Cargo.toml
+++ b/arrow-arith/Cargo.toml
@@ -44,9 +44,5 @@ num = { version = "0.4", default-features = false, features = ["std"] }
 
 [dev-dependencies]
 
-[package.metadata.docs.rs]
-features = ["dyn_arith_dict"]
-
 [features]
-dyn_arith_dict = []
 simd = ["arrow-array/simd"]
diff --git a/arrow-arith/src/arithmetic.rs b/arrow-arith/src/arithmetic.rs
index c3c5cb864..8e7ab4404 100644
--- a/arrow-arith/src/arithmetic.rs
+++ b/arrow-arith/src/arithmetic.rs
@@ -89,48 +89,6 @@ where
     math_checked_op(left, right, op)
 }
 
-/// Helper function for operations where a valid `0` on the right array should
-/// result in an [ArrowError::DivideByZero], namely the division and modulo operations
-///
-/// # Errors
-///
-/// This function errors if:
-/// * the arrays have different lengths
-/// * there is an element where both left and right values are valid and the right value is `0`
-#[cfg(feature = "dyn_arith_dict")]
-fn math_checked_divide_op_on_iters<T, F>(
-    left: impl Iterator<Item = Option<T::Native>>,
-    right: impl Iterator<Item = Option<T::Native>>,
-    op: F,
-    nulls: Option<arrow_buffer::NullBuffer>,
-) -> Result<PrimitiveArray<T>, ArrowError>
-where
-    T: ArrowNumericType,
-    F: Fn(T::Native, T::Native) -> Result<T::Native, ArrowError>,
-{
-    let buffer = if nulls.is_some() {
-        let values = left.zip(right).map(|(left, right)| {
-            if let (Some(l), Some(r)) = (left, right) {
-                op(l, r)
-            } else {
-                Ok(T::default_value())
-            }
-        });
-        // Safety: Iterator comes from a PrimitiveArray which reports its size correctly
-        unsafe { arrow_buffer::Buffer::try_from_trusted_len_iter(values) }
-    } else {
-        // no value is null
-        let values = left
-            .map(|l| l.unwrap())
-            .zip(right.map(|r| r.unwrap()))
-            .map(|(left, right)| op(left, right));
-        // Safety: Iterator comes from a PrimitiveArray which reports its size correctly
-        unsafe { arrow_buffer::Buffer::try_from_trusted_len_iter(values) }
-    }?;
-
-    Ok(PrimitiveArray::new(buffer.into(), nulls))
-}
-
 /// Calculates the modulus operation `left % right` on two SIMD inputs.
 /// The lower-most bits of `valid_mask` specify which vector lanes are considered as valid.
 ///
@@ -358,290 +316,6 @@ where
     Ok(PrimitiveArray::new(result.into(), nulls))
 }
 
-/// Applies $OP to $LEFT and $RIGHT which are two dictionaries which have (the same) key type $KT
-#[cfg(feature = "dyn_arith_dict")]
-macro_rules! typed_dict_op {
-    ($LEFT: expr, $RIGHT: expr, $OP: expr, $KT: tt, $MATH_OP: ident) => {{
-        match ($LEFT.value_type(), $RIGHT.value_type()) {
-            (DataType::Int8, DataType::Int8) => {
-                let array = $MATH_OP::<$KT, Int8Type, _>($LEFT, $RIGHT, $OP)?;
-                Ok(Arc::new(array))
-            }
-            (DataType::Int16, DataType::Int16) => {
-                let array = $MATH_OP::<$KT, Int16Type, _>($LEFT, $RIGHT, $OP)?;
-                Ok(Arc::new(array))
-            }
-            (DataType::Int32, DataType::Int32) => {
-                let array = $MATH_OP::<$KT, Int32Type, _>($LEFT, $RIGHT, $OP)?;
-                Ok(Arc::new(array))
-            }
-            (DataType::Int64, DataType::Int64) => {
-                let array = $MATH_OP::<$KT, Int64Type, _>($LEFT, $RIGHT, $OP)?;
-                Ok(Arc::new(array))
-            }
-            (DataType::UInt8, DataType::UInt8) => {
-                let array = $MATH_OP::<$KT, UInt8Type, _>($LEFT, $RIGHT, $OP)?;
-                Ok(Arc::new(array))
-            }
-            (DataType::UInt16, DataType::UInt16) => {
-                let array = $MATH_OP::<$KT, UInt16Type, _>($LEFT, $RIGHT, $OP)?;
-                Ok(Arc::new(array))
-            }
-            (DataType::UInt32, DataType::UInt32) => {
-                let array = $MATH_OP::<$KT, UInt32Type, _>($LEFT, $RIGHT, $OP)?;
-                Ok(Arc::new(array))
-            }
-            (DataType::UInt64, DataType::UInt64) => {
-                let array = $MATH_OP::<$KT, UInt64Type, _>($LEFT, $RIGHT, $OP)?;
-                Ok(Arc::new(array))
-            }
-            (DataType::Float32, DataType::Float32) => {
-                let array = $MATH_OP::<$KT, Float32Type, _>($LEFT, $RIGHT, $OP)?;
-                Ok(Arc::new(array))
-            }
-            (DataType::Float64, DataType::Float64) => {
-                let array = $MATH_OP::<$KT, Float64Type, _>($LEFT, $RIGHT, $OP)?;
-                Ok(Arc::new(array))
-            }
-            (DataType::Decimal128(_, s1), DataType::Decimal128(_, s2)) if s1 == s2 => {
-                let array = $MATH_OP::<$KT, Decimal128Type, _>($LEFT, $RIGHT, $OP)?;
-                Ok(Arc::new(array))
-            }
-            (DataType::Decimal256(_, s1), DataType::Decimal256(_, s2)) if s1 == s2 => {
-                let array = $MATH_OP::<$KT, Decimal256Type, _>($LEFT, $RIGHT, $OP)?;
-                Ok(Arc::new(array))
-            }
-            (t1, t2) => Err(ArrowError::CastError(format!(
-                "Cannot perform arithmetic operation on two dictionary arrays of different value types ({} and {})",
-                t1, t2
-            ))),
-        }
-    }};
-}
-
-#[cfg(feature = "dyn_arith_dict")]
-macro_rules! typed_dict_math_op {
-   // Applies `LEFT OP RIGHT` when `LEFT` and `RIGHT` both are `DictionaryArray`
-    ($LEFT: expr, $RIGHT: expr, $OP: expr, $MATH_OP: ident) => {{
-        match ($LEFT.data_type(), $RIGHT.data_type()) {
-            (DataType::Dictionary(left_key_type, _), DataType::Dictionary(right_key_type, _))=> {
-                match (left_key_type.as_ref(), right_key_type.as_ref()) {
-                    (DataType::Int8, DataType::Int8) => {
-                        let left = as_dictionary_array::<Int8Type>($LEFT);
-                        let right = as_dictionary_array::<Int8Type>($RIGHT);
-                        typed_dict_op!(left, right, $OP, Int8Type, $MATH_OP)
-                    }
-                    (DataType::Int16, DataType::Int16) => {
-                        let left = as_dictionary_array::<Int16Type>($LEFT);
-                        let right = as_dictionary_array::<Int16Type>($RIGHT);
-                        typed_dict_op!(left, right, $OP, Int16Type, $MATH_OP)
-                    }
-                    (DataType::Int32, DataType::Int32) => {
-                        let left = as_dictionary_array::<Int32Type>($LEFT);
-                        let right = as_dictionary_array::<Int32Type>($RIGHT);
-                        typed_dict_op!(left, right, $OP, Int32Type, $MATH_OP)
-                    }
-                    (DataType::Int64, DataType::Int64) => {
-                        let left = as_dictionary_array::<Int64Type>($LEFT);
-                        let right = as_dictionary_array::<Int64Type>($RIGHT);
-                        typed_dict_op!(left, right, $OP, Int64Type, $MATH_OP)
-                    }
-                    (DataType::UInt8, DataType::UInt8) => {
-                        let left = as_dictionary_array::<UInt8Type>($LEFT);
-                        let right = as_dictionary_array::<UInt8Type>($RIGHT);
-                        typed_dict_op!(left, right, $OP, UInt8Type, $MATH_OP)
-                    }
-                    (DataType::UInt16, DataType::UInt16) => {
-                        let left = as_dictionary_array::<UInt16Type>($LEFT);
-                        let right = as_dictionary_array::<UInt16Type>($RIGHT);
-                        typed_dict_op!(left, right, $OP, UInt16Type, $MATH_OP)
-                    }
-                    (DataType::UInt32, DataType::UInt32) => {
-                        let left = as_dictionary_array::<UInt32Type>($LEFT);
-                        let right = as_dictionary_array::<UInt32Type>($RIGHT);
-                        typed_dict_op!(left, right, $OP, UInt32Type, $MATH_OP)
-                    }
-                    (DataType::UInt64, DataType::UInt64) => {
-                        let left = as_dictionary_array::<UInt64Type>($LEFT);
-                        let right = as_dictionary_array::<UInt64Type>($RIGHT);
-                        typed_dict_op!(left, right, $OP, UInt64Type, $MATH_OP)
-                    }
-                    (t1, t2) => Err(ArrowError::CastError(format!(
-                        "Cannot perform arithmetic operation on two dictionary arrays of different key types ({} and {})",
-                        t1, t2
-                    ))),
-                }
-            }
-            (t1, t2) => Err(ArrowError::CastError(format!(
-                "Cannot perform arithmetic operation on dictionary array with non-dictionary array ({} and {})",
-                t1, t2
-            ))),
-        }
-    }};
-}
-
-#[cfg(not(feature = "dyn_arith_dict"))]
-macro_rules! typed_dict_math_op {
-   // Applies `LEFT OP RIGHT` when `LEFT` and `RIGHT` both are `DictionaryArray`
-    ($LEFT: expr, $RIGHT: expr, $OP: expr, $MATH_OP: ident) => {{
-        Err(ArrowError::CastError(format!(
-            "Arithmetic on arrays of type {} with array of type {} requires \"dyn_arith_dict\" feature",
-            $LEFT.data_type(), $RIGHT.data_type()
-        )))
-    }};
-}
-
-/// Perform given operation on two `DictionaryArray`s.
-/// Returns an error if the two arrays have different value type
-#[cfg(feature = "dyn_arith_dict")]
-fn math_op_dict<K, T, F>(
-    left: &DictionaryArray<K>,
-    right: &DictionaryArray<K>,
-    op: F,
-) -> Result<PrimitiveArray<T>, ArrowError>
-where
-    K: ArrowDictionaryKeyType + ArrowNumericType,
-    T: ArrowNumericType,
-    F: Fn(T::Native, T::Native) -> T::Native,
-{
-    if left.len() != right.len() {
-        return Err(ArrowError::ComputeError(format!(
-            "Cannot perform operation on arrays of different length ({}, {})",
-            left.len(),
-            right.len()
-        )));
-    }
-
-    // Safety justification: Since the inputs are valid Arrow arrays, all values are
-    // valid indexes into the dictionary (which is verified during construction)
-
-    let left_iter = unsafe {
-        left.values()
-            .as_any()
-            .downcast_ref::<PrimitiveArray<T>>()
-            .unwrap()
-            .take_iter_unchecked(left.keys_iter())
-    };
-
-    let right_iter = unsafe {
-        right
-            .values()
-            .as_any()
-            .downcast_ref::<PrimitiveArray<T>>()
-            .unwrap()
-            .take_iter_unchecked(right.keys_iter())
-    };
-
-    let result = left_iter
-        .zip(right_iter)
-        .map(|(left_value, right_value)| {
-            if let (Some(left), Some(right)) = (left_value, right_value) {
-                Some(op(left, right))
-            } else {
-                None
-            }
-        })
-        .collect();
-
-    Ok(result)
-}
-
-/// Perform given operation on two `DictionaryArray`s.
-/// Returns an error if the two arrays have different value type
-#[cfg(feature = "dyn_arith_dict")]
-fn math_checked_op_dict<K, T, F>(
-    left: &DictionaryArray<K>,
-    right: &DictionaryArray<K>,
-    op: F,
-) -> Result<PrimitiveArray<T>, ArrowError>
-where
-    K: ArrowDictionaryKeyType + ArrowNumericType,
-    T: ArrowNumericType,
-    F: Fn(T::Native, T::Native) -> Result<T::Native, ArrowError>,
-{
-    // left and right's value types are supposed to be same as guaranteed by the caller macro now.
-    if left.value_type() != T::DATA_TYPE {
-        return Err(ArrowError::NotYetImplemented(format!(
-            "Cannot perform provided operation on dictionary array of value type {}",
-            left.value_type()
-        )));
-    }
-
-    let left = left.downcast_dict::<PrimitiveArray<T>>().unwrap();
-    let right = right.downcast_dict::<PrimitiveArray<T>>().unwrap();
-
-    try_binary(left, right, op)
-}
-
-/// Helper function for operations where a valid `0` on the right array should
-/// result in an [ArrowError::DivideByZero], namely the division and modulo operations
-///
-/// # Errors
-///
-/// This function errors if:
-/// * the arrays have different lengths
-/// * there is an element where both left and right values are valid and the right value is `0`
-#[cfg(feature = "dyn_arith_dict")]
-fn math_divide_checked_op_dict<K, T, F>(
-    left: &DictionaryArray<K>,
-    right: &DictionaryArray<K>,
-    op: F,
-) -> Result<PrimitiveArray<T>, ArrowError>
-where
-    K: ArrowDictionaryKeyType + ArrowNumericType,
-    T: ArrowNumericType,
-    F: Fn(T::Native, T::Native) -> Result<T::Native, ArrowError>,
-{
-    if left.len() != right.len() {
-        return Err(ArrowError::ComputeError(format!(
-            "Cannot perform operation on arrays of different length ({}, {})",
-            left.len(),
-            right.len()
-        )));
-    }
-
-    let nulls = arrow_buffer::NullBuffer::union(left.nulls(), right.nulls());
-
-    // Safety justification: Since the inputs are valid Arrow arrays, all values are
-    // valid indexes into the dictionary (which is verified during construction)
-
-    let left_iter = unsafe {
-        left.values()
-            .as_any()
-            .downcast_ref::<PrimitiveArray<T>>()
-            .unwrap()
-            .take_iter_unchecked(left.keys_iter())
-    };
-
-    let right_iter = unsafe {
-        right
-            .values()
-            .as_any()
-            .downcast_ref::<PrimitiveArray<T>>()
-            .unwrap()
-            .take_iter_unchecked(right.keys_iter())
-    };
-
-    math_checked_divide_op_on_iters(left_iter, right_iter, op, nulls)
-}
-
-#[cfg(feature = "dyn_arith_dict")]
-fn math_divide_safe_op_dict<K, T, F>(
-    left: &DictionaryArray<K>,
-    right: &DictionaryArray<K>,
-    op: F,
-) -> Result<ArrayRef, ArrowError>
-where
-    K: ArrowDictionaryKeyType + ArrowNumericType,
-    T: ArrowNumericType,
-    F: Fn(T::Native, T::Native) -> Option<T::Native>,
-{
-    let left = left.downcast_dict::<PrimitiveArray<T>>().unwrap();
-    let right = right.downcast_dict::<PrimitiveArray<T>>().unwrap();
-    let array: PrimitiveArray<T> = binary_opt::<_, _, _, T>(left, right, op)?;
-    Ok(Arc::new(array) as ArrayRef)
-}
-
 fn math_safe_divide_op<LT, RT, F>(
     left: &PrimitiveArray<LT>,
     right: &PrimitiveArray<RT>,
@@ -687,9 +361,6 @@ pub fn add_checked<T: ArrowNumericType>(
 /// For an overflow-checking variant, use `add_dyn_checked` instead.
 pub fn add_dyn(left: &dyn Array, right: &dyn Array) -> Result<ArrayRef, ArrowError> {
     match left.data_type() {
-        DataType::Dictionary(_, _) => {
-            typed_dict_math_op!(left, right, |a, b| a.add_wrapping(b), math_op_dict)
-        }
         DataType::Date32 => {
             let l = left.as_primitive::<Date32Type>();
             match right.data_type() {
@@ -870,14 +541,6 @@ pub fn add_dyn_checked(
     right: &dyn Array,
 ) -> Result<ArrayRef, ArrowError> {
     match left.data_type() {
-        DataType::Dictionary(_, _) => {
-            typed_dict_math_op!(
-                left,
-                right,
-                |a, b| a.add_checked(b),
-                math_checked_op_dict
-            )
-        }
         DataType::Date32 => {
             let l = left.as_primitive::<Date32Type>();
             match right.data_type() {
@@ -1027,9 +690,6 @@ pub fn subtract_checked<T: ArrowNumericType>(
 /// For an overflow-checking variant, use `subtract_dyn_checked` instead.
 pub fn subtract_dyn(left: &dyn Array, right: &dyn Array) -> Result<ArrayRef, ArrowError> {
     match left.data_type() {
-        DataType::Dictionary(_, _) => {
-            typed_dict_math_op!(left, right, |a, b| a.sub_wrapping(b), math_op_dict)
-        }
         DataType::Date32 => {
             let l = left.as_primitive::<Date32Type>();
             match right.data_type() {
@@ -1218,14 +878,6 @@ pub fn subtract_dyn_checked(
     right: &dyn Array,
 ) -> Result<ArrayRef, ArrowError> {
     match left.data_type() {
-        DataType::Dictionary(_, _) => {
-            typed_dict_math_op!(
-                left,
-                right,
-                |a, b| a.sub_checked(b),
-                math_checked_op_dict
-            )
-        }
         DataType::Date32 => {
             let l = left.as_primitive::<Date32Type>();
             match right.data_type() {
@@ -1445,22 +1097,15 @@ pub fn multiply_checked<T: ArrowNumericType>(
 /// This doesn't detect overflow. Once overflowing, the result will wrap around.
 /// For an overflow-checking variant, use `multiply_dyn_checked` instead.
 pub fn multiply_dyn(left: &dyn Array, right: &dyn Array) -> Result<ArrayRef, ArrowError> {
-    match left.data_type() {
-        DataType::Dictionary(_, _) => {
-            typed_dict_math_op!(left, right, |a, b| a.mul_wrapping(b), math_op_dict)
-        }
-        _ => {
-            downcast_primitive_array!(
-                (left, right) => {
-                    math_op(left, right, |a, b| a.mul_wrapping(b)).map(|a| Arc::new(a) as ArrayRef)
-                }
-                _ => Err(ArrowError::CastError(format!(
-                    "Unsupported data type {}, {}",
-                    left.data_type(), right.data_type()
-                )))
-            )
+    downcast_primitive_array!(
+        (left, right) => {
+            math_op(left, right, |a, b| a.mul_wrapping(b)).map(|a| Arc::new(a) as ArrayRef)
         }
-    }
+        _ => Err(ArrowError::CastError(format!(
+            "Unsupported data type {}, {}",
+            left.data_type(), right.data_type()
+        )))
+    )
 }
 
 /// Perform `left * right` operation on two arrays. If either left or right value is null
@@ -1472,37 +1117,15 @@ pub fn multiply_dyn_checked(
     left: &dyn Array,
     right: &dyn Array,
 ) -> Result<ArrayRef, ArrowError> {
-    match left.data_type() {
-        DataType::Dictionary(_, _) => {
-            typed_dict_math_op!(
-                left,
-                right,
-                |a, b| a.mul_checked(b),
-                math_checked_op_dict
-            )
-        }
-        _ => {
-            downcast_primitive_array!(
-                (left, right) => {
-                    math_checked_op(left, right, |a, b| a.mul_checked(b)).map(|a| Arc::new(a) as ArrayRef)
-                }
-                _ => Err(ArrowError::CastError(format!(
-                    "Unsupported data type {}, {}",
-                    left.data_type(), right.data_type()
-                )))
-            )
+    downcast_primitive_array!(
+        (left, right) => {
+            math_checked_op(left, right, |a, b| a.mul_checked(b)).map(|a| Arc::new(a) as ArrayRef)
         }
-    }
-}
-
-#[cfg(feature = "dyn_arith_dict")]
-fn get_precision_scale(dt: &DataType) -> Result<(u8, i8), ArrowError> {
-    match dt {
-        DataType::Decimal128(precision, scale) => Ok((*precision, *scale)),
-        _ => Err(ArrowError::ComputeError(
-            "Cannot get precision and scale from non-decimal type".to_string(),
-        )),
-    }
+        _ => Err(ArrowError::CastError(format!(
+            "Unsupported data type {}, {}",
+            left.data_type(), right.data_type()
+        )))
+    )
 }
 
 /// Returns the precision and scale of the result of a multiplication of two decimal types,
@@ -1528,7 +1151,6 @@ fn get_fixed_point_info(
     Ok((precision, product_scale, divisor))
 }
 
-#[cfg(feature = "dyn_arith_dict")]
 /// Perform `left * right` operation on two decimal arrays. If either left or right value is
 /// null then the result is also null.
 ///
@@ -1549,45 +1171,6 @@ pub fn multiply_fixed_point_dyn(
     required_scale: i8,
 ) -> Result<ArrayRef, ArrowError> {
     match (left.data_type(), right.data_type()) {
-        (
-            DataType::Dictionary(_, lhs_value_type),
-            DataType::Dictionary(_, rhs_value_type),
-        ) if matches!(lhs_value_type.as_ref(), &DataType::Decimal128(_, _))
-            && matches!(rhs_value_type.as_ref(), &DataType::Decimal128(_, _)) =>
-        {
-            downcast_dictionary_array!(
-                left => match left.values().data_type() {
-                    DataType::Decimal128(_, _) => {
-                        let lhs_precision_scale = get_precision_scale(lhs_value_type.as_ref())?;
-                        let rhs_precision_scale = get_precision_scale(rhs_value_type.as_ref())?;
-
-                        let (precision, product_scale, divisor) = get_fixed_point_info(lhs_precision_scale, rhs_precision_scale, required_scale)?;
-
-                        let right = as_dictionary_array::<_>(right);
-
-                        if required_scale == product_scale {
-                            let mul = multiply_dyn(left, right)?;
-                            let array = mul.as_any().downcast_ref::<Decimal128Array>().unwrap();
-                            let array = array.clone().with_precision_and_scale(precision, required_scale)?;
-                            return Ok(Arc::new(array))
-                        }
-
-                        let array = math_op_dict::<_, Decimal128Type, _>(left, right, |a, b| {
-                            let a = i256::from_i128(a);
-                            let b = i256::from_i128(b);
-
-                            let mut mul = a.wrapping_mul(b);
-                            mul = divide_and_round::<Decimal256Type>(mul, divisor);
-                            mul.as_i128()
-                        }).and_then(|a| a.with_precision_and_scale(precision, required_scale))?;
-
-                        Ok(Arc::new(array))
-                    }
-                    t => unreachable!("Unsupported dictionary value type {}", t),
-                },
-                t => unreachable!("Unsupported data type {}", t),
-            )
-        }
         (DataType::Decimal128(_, _), DataType::Decimal128(_, _)) => {
             let left = left.as_any().downcast_ref::<Decimal128Array>().unwrap();
             let right = right.as_any().downcast_ref::<Decimal128Array>().unwrap();
@@ -1782,39 +1365,21 @@ pub fn modulus<T: ArrowNumericType>(
 /// then the result is also null. If any right hand value is zero then the result of this
 /// operation will be `Err(ArrowError::DivideByZero)`.
 pub fn modulus_dyn(left: &dyn Array, right: &dyn Array) -> Result<ArrayRef, ArrowError> {
-    match left.data_type() {
-        DataType::Dictionary(_, _) => {
-            typed_dict_math_op!(
-                left,
-                right,
-                |a, b| {
-                    if b.is_zero() {
-                        Err(ArrowError::DivideByZero)
-                    } else {
-                        Ok(a.mod_wrapping(b))
-                    }
-                },
-                math_divide_checked_op_dict
-            )
+    downcast_primitive_array!(
+        (left, right) => {
+            math_checked_divide_op(left, right, |a, b| {
+                if b.is_zero() {
+                    Err(ArrowError::DivideByZero)
+                } else {
+                    Ok(a.mod_wrapping(b))
+                }
+            }).map(|a| Arc::new(a) as ArrayRef)
         }
-        _ => {
-            downcast_primitive_array!(
-                (left, right) => {
-                    math_checked_divide_op(left, right, |a, b| {
-                        if b.is_zero() {
-                            Err(ArrowError::DivideByZero)
-                        } else {
-                            Ok(a.mod_wrapping(b))
-                        }
-                    }).map(|a| Arc::new(a) as ArrayRef)
-                }
-                _ => Err(ArrowError::CastError(format!(
-                    "Unsupported data type {}, {}",
-                    left.data_type(), right.data_type()
-                )))
-            )
-        }
-    }
+        _ => Err(ArrowError::CastError(format!(
+            "Unsupported data type {}, {}",
+            left.data_type(), right.data_type()
+        )))
+    )
 }
 
 /// Perform `left / right` operation on two arrays. If either left or right value is null
@@ -1869,39 +1434,21 @@ pub fn divide_opt<T: ArrowNumericType>(
 /// This doesn't detect overflow. Once overflowing, the result will wrap around.
 /// For an overflow-checking variant, use `divide_dyn_checked` instead.
 pub fn divide_dyn(left: &dyn Array, right: &dyn Array) -> Result<ArrayRef, ArrowError> {
-    match left.data_type() {
-        DataType::Dictionary(_, _) => {
-            typed_dict_math_op!(
-                left,
-                right,
-                |a, b| {
-                    if b.is_zero() {
-                        Err(ArrowError::DivideByZero)
-                    } else {
-                        Ok(a.div_wrapping(b))
-                    }
-                },
-                math_divide_checked_op_dict
-            )
+    downcast_primitive_array!(
+        (left, right) => {
+            math_checked_divide_op(left, right, |a, b| {
+                if b.is_zero() {
+                    Err(ArrowError::DivideByZero)
+                } else {
+                    Ok(a.div_wrapping(b))
+                }
+            }).map(|a| Arc::new(a) as ArrayRef)
         }
-        _ => {
-            downcast_primitive_array!(
-                (left, right) => {
-                    math_checked_divide_op(left, right, |a, b| {
-                        if b.is_zero() {
-                            Err(ArrowError::DivideByZero)
-                        } else {
-                            Ok(a.div_wrapping(b))
-                        }
-                    }).map(|a| Arc::new(a) as ArrayRef)
-                }
-                _ => Err(ArrowError::CastError(format!(
-                    "Unsupported data type {}, {}",
-                    left.data_type(), right.data_type()
-                )))
-            )
-        }
-    }
+        _ => Err(ArrowError::CastError(format!(
+            "Unsupported data type {}, {}",
+            left.data_type(), right.data_type()
+        )))
+    )
 }
 
 /// Perform `left / right` operation on two arrays. If either left or right value is null
@@ -1914,27 +1461,15 @@ pub fn divide_dyn_checked(
     left: &dyn Array,
     right: &dyn Array,
 ) -> Result<ArrayRef, ArrowError> {
-    match left.data_type() {
-        DataType::Dictionary(_, _) => {
-            typed_dict_math_op!(
-                left,
-                right,
-                |a, b| a.div_checked(b),
-                math_divide_checked_op_dict
-            )
+    downcast_primitive_array!(
+        (left, right) => {
+            math_checked_divide_op(left, right, |a, b| a.div_checked(b)).map(|a| Arc::new(a) as ArrayRef)
         }
-        _ => {
-            downcast_primitive_array!(
-                (left, right) => {
-                    math_checked_divide_op(left, right, |a, b| a.div_checked(b)).map(|a| Arc::new(a) as ArrayRef)
-                }
-                _ => Err(ArrowError::CastError(format!(
-                    "Unsupported data type {}, {}",
-                    left.data_type(), right.data_type()
-                )))
-            )
-        }
-    }
+        _ => Err(ArrowError::CastError(format!(
+            "Unsupported data type {}, {}",
+            left.data_type(), right.data_type()
+        )))
+    )
 }
 
 /// Perform `left / right` operation on two arrays. If either left or right value is null
@@ -1950,39 +1485,21 @@ pub fn divide_dyn_opt(
     left: &dyn Array,
     right: &dyn Array,
 ) -> Result<ArrayRef, ArrowError> {
-    match left.data_type() {
-        DataType::Dictionary(_, _) => {
-            typed_dict_math_op!(
-                left,
-                right,
-                |a, b| {
-                    if b.is_zero() {
-                        None
-                    } else {
-                        Some(a.div_wrapping(b))
-                    }
-                },
-                math_divide_safe_op_dict
-            )
+    downcast_primitive_array!(
+        (left, right) => {
+            math_safe_divide_op(left, right, |a, b| {
+                if b.is_zero() {
+                    None
+                } else {
+                    Some(a.div_wrapping(b))
+                }
+            })
         }
-        _ => {
-            downcast_primitive_array!(
-                (left, right) => {
-                    math_safe_divide_op(left, right, |a, b| {
-                        if b.is_zero() {
-                            None
-                        } else {
-                            Some(a.div_wrapping(b))
-                        }
-                    })
-                }
-                _ => Err(ArrowError::CastError(format!(
-                    "Unsupported data type {}, {}",
-                    left.data_type(), right.data_type()
-                )))
-            )
-        }
-    }
+        _ => Err(ArrowError::CastError(format!(
+            "Unsupported data type {}, {}",
+            left.data_type(), right.data_type()
+        )))
+    )
 }
 
 /// Perform `left / right` operation on two arrays without checking for
@@ -2279,34 +1796,6 @@ mod tests {
         assert_eq!(17, c.value(4));
     }
 
-    #[test]
-    #[cfg(feature = "dyn_arith_dict")]
-    fn test_primitive_array_add_dyn_dict() {
-        let mut builder = PrimitiveDictionaryBuilder::<Int8Type, Int32Type>::new();
-        builder.append(5).unwrap();
-        builder.append(6).unwrap();
-        builder.append(7).unwrap();
-        builder.append(8).unwrap();
-        builder.append(9).unwrap();
-        let a = builder.finish();
-
-        let mut builder = PrimitiveDictionaryBuilder::<Int8Type, Int32Type>::new();
-        builder.append(6).unwrap();
-        builder.append(7).unwrap();
-        builder.append(8).unwrap();
-        builder.append_null();
-        builder.append(10).unwrap();
-        let b = builder.finish();
-
-        let c = add_dyn(&a, &b).unwrap();
-        let c = c.as_any().downcast_ref::<Int32Array>().unwrap();
-        assert_eq!(11, c.value(0));
-        assert_eq!(13, c.value(1));
-        assert_eq!(15, c.value(2));
-        assert!(c.is_null(3));
-        assert_eq!(19, c.value(4));
-    }
-
     #[test]
     fn test_primitive_array_add_scalar_dyn() {
         let a = Int32Array::from(vec![Some(5), Some(6), Some(7), None, Some(9)]);
@@ -2452,34 +1941,6 @@ mod tests {
         );
     }
 
-    #[test]
-    #[cfg(feature = "dyn_arith_dict")]
-    fn test_primitive_array_subtract_dyn_dict() {
-        let mut builder = PrimitiveDictionaryBuilder::<Int8Type, Int32Type>::new();
-        builder.append(15).unwrap();
-        builder.append(8).unwrap();
-        builder.append(7).unwrap();
-        builder.append(8).unwrap();
-        builder.append(20).unwrap();
-        let a = builder.finish();
-
-        let mut builder = PrimitiveDictionaryBuilder::<Int8Type, Int32Type>::new();
-        builder.append(6).unwrap();
-        builder.append(7).unwrap();
-        builder.append(8).unwrap();
-        builder.append_null();
-        builder.append(10).unwrap();
-        let b = builder.finish();
-
-        let c = subtract_dyn(&a, &b).unwrap();
-        let c = c.as_any().downcast_ref::<Int32Array>().unwrap();
-        assert_eq!(9, c.value(0));
-        assert_eq!(1, c.value(1));
-        assert_eq!(-1, c.value(2));
-        assert!(c.is_null(3));
-        assert_eq!(10, c.value(4));
-    }
-
     #[test]
     fn test_primitive_array_subtract_scalar_dyn() {
         let a = Int32Array::from(vec![Some(5), Some(6), Some(7), None, Some(9)]);
@@ -2531,34 +1992,6 @@ mod tests {
         assert_eq!(72, c.value(4));
     }
 
-    #[test]
-    #[cfg(feature = "dyn_arith_dict")]
-    fn test_primitive_array_multiply_dyn_dict() {
-        let mut builder = PrimitiveDictionaryBuilder::<Int8Type, Int32Type>::new();
-        builder.append(5).unwrap();
-        builder.append(6).unwrap();
-        builder.append(7).unwrap();
-        builder.append(8).unwrap();
-        builder.append(9).unwrap();
-        let a = builder.finish();
-
-        let mut builder = PrimitiveDictionaryBuilder::<Int8Type, Int32Type>::new();
-        builder.append(6).unwrap();
-        builder.append(7).unwrap();
-        builder.append(8).unwrap();
-        builder.append_null();
-        builder.append(10).unwrap();
-        let b = builder.finish();
-
-        let c = multiply_dyn(&a, &b).unwrap();
-        let c = c.as_any().downcast_ref::<Int32Array>().unwrap();
-        assert_eq!(30, c.value(0));
-        assert_eq!(42, c.value(1));
-        assert_eq!(56, c.value(2));
-        assert!(c.is_null(3));
-        assert_eq!(90, c.value(4));
-    }
-
     #[test]
     fn test_primitive_array_divide_dyn() {
         let a = Int32Array::from(vec![Some(15), Some(6), Some(1), Some(8), Some(9)]);
@@ -2572,34 +2005,6 @@ mod tests {
         assert_eq!(3, c.value(4));
     }
 
-    #[test]
-    #[cfg(feature = "dyn_arith_dict")]
-    fn test_primitive_array_divide_dyn_dict() {
-        let mut builder = PrimitiveDictionaryBuilder::<Int8Type, Int32Type>::new();
-        builder.append(15).unwrap();
-        builder.append(6).unwrap();
-        builder.append(1).unwrap();
-        builder.append(8).unwrap();
-        builder.append(9).unwrap();
-        let a = builder.finish();
-
-        let mut builder = PrimitiveDictionaryBuilder::<Int8Type, Int32Type>::new();
-        builder.append(5).unwrap();
-        builder.append(3).unwrap();
-        builder.append(1).unwrap();
-        builder.append_null();
-        builder.append(3).unwrap();
-        let b = builder.finish();
-
-        let c = divide_dyn(&a, &b).unwrap();
-        let c = c.as_any().downcast_ref::<Int32Array>().unwrap();
-        assert_eq!(3, c.value(0));
-        assert_eq!(2, c.value(1));
-        assert_eq!(1, c.value(2));
-        assert!(c.is_null(3));
-        assert_eq!(3, c.value(4));
-    }
-
     #[test]
     fn test_primitive_array_multiply_scalar_dyn() {
         let a = Int32Array::from(vec![Some(5), Some(6), Some(7), None, Some(9)]);
@@ -3154,40 +2559,6 @@ mod tests {
         divide_dyn(&a, &b).unwrap();
     }
 
-    #[test]
-    #[should_panic(expected = "DivideByZero")]
-    #[cfg(feature = "dyn_arith_dict")]
-    fn test_int_array_divide_dyn_by_zero_dict() {
-        let mut builder =
-            PrimitiveDictionaryBuilder::<Int8Type, Int32Type>::with_capacity(1, 1);
-        builder.append(15).unwrap();
-        let a = builder.finish();
-
-        let mut builder =
-            PrimitiveDictionaryBuilder::<Int8Type, Int32Type>::with_capacity(1, 1);
-        builder.append(0).unwrap();
-        let b = builder.finish();
-
-        divide_dyn(&a, &b).unwrap();
-    }
-
-    #[test]
-    #[should_panic(expected = "DivideByZero")]
-    #[cfg(feature = "dyn_arith_dict")]
-    fn test_f32_dict_array_divide_dyn_by_zero() {
-        let mut builder =
-            PrimitiveDictionaryBuilder::<Int8Type, Float32Type>::with_capacity(1, 1);
-        builder.append(1.5).unwrap();
-        let a = builder.finish();
-
-        let mut builder =
-            PrimitiveDictionaryBuilder::<Int8Type, Float32Type>::with_capacity(1, 1);
-        builder.append(0.0).unwrap();
-        let b = builder.finish();
-
-        divide_dyn(&a, &b).unwrap();
-    }
-
     #[test]
     #[should_panic(expected = "DivideByZero")]
     fn test_i32_array_modulus_by_zero() {
@@ -3449,30 +2820,6 @@ mod tests {
         overflow.expect_err("overflow should be detected");
     }
 
-    #[test]
-    #[cfg(feature = "dyn_arith_dict")]
-    fn test_dictionary_add_dyn_wrapping_overflow() {
-        let mut builder =
-            PrimitiveDictionaryBuilder::<Int8Type, Int32Type>::with_capacity(2, 2);
-        builder.append(i32::MAX).unwrap();
-        builder.append(i32::MIN).unwrap();
-        let a = builder.finish();
-
-        let mut builder =
-            PrimitiveDictionaryBuilder::<Int8Type, Int32Type>::with_capacity(2, 2);
-        builder.append(1).unwrap();
-        builder.append(1).unwrap();
-        let b = builder.finish();
-
-        let wrapped = add_dyn(&a, &b).unwrap();
-        let expected =
-            Arc::new(Int32Array::from(vec![-2147483648, -2147483647])) as ArrayRef;
-        assert_eq!(&expected, &wrapped);
-
-        let overflow = add_dyn_checked(&a, &b);
-        overflow.expect_err("overflow should be detected");
-    }
-
     #[test]
     fn test_primitive_subtract_dyn_wrapping_overflow() {
         let a = Int32Array::from(vec![-2]);
@@ -3486,27 +2833,6 @@ mod tests {
         overflow.expect_err("overflow should be detected");
     }
 
-    #[test]
-    #[cfg(feature = "dyn_arith_dict")]
-    fn test_dictionary_subtract_dyn_wrapping_overflow() {
-        let mut builder =
-            PrimitiveDictionaryBuilder::<Int8Type, Int32Type>::with_capacity(1, 1);
-        builder.append(-2).unwrap();
-        let a = builder.finish();
-
-        let mut builder =
-            PrimitiveDictionaryBuilder::<Int8Type, Int32Type>::with_capacity(1, 1);
-        builder.append(i32::MAX).unwrap();
-        let b = builder.finish();
-
-        let wrapped = subtract_dyn(&a, &b).unwrap();
-        let expected = Arc::new(Int32Array::from(vec![i32::MAX])) as ArrayRef;
-        assert_eq!(&expected, &wrapped);
-
-        let overflow = subtract_dyn_checked(&a, &b);
-        overflow.expect_err("overflow should be detected");
-    }
-
     #[test]
     fn test_primitive_mul_dyn_wrapping_overflow() {
         let a = Int32Array::from(vec![10]);
@@ -3520,27 +2846,6 @@ mod tests {
         overflow.expect_err("overflow should be detected");
     }
 
-    #[test]
-    #[cfg(feature = "dyn_arith_dict")]
-    fn test_dictionary_mul_dyn_wrapping_overflow() {
-        let mut builder =
-            PrimitiveDictionaryBuilder::<Int8Type, Int32Type>::with_capacity(1, 1);
-        builder.append(10).unwrap();
-        let a = builder.finish();
-
-        let mut builder =
-            PrimitiveDictionaryBuilder::<Int8Type, Int32Type>::with_capacity(1, 1);
-        builder.append(i32::MAX).unwrap();
-        let b = builder.finish();
-
-        let wrapped = multiply_dyn(&a, &b).unwrap();
-        let expected = Arc::new(Int32Array::from(vec![-10])) as ArrayRef;
-        assert_eq!(&expected, &wrapped);
-
-        let overflow = multiply_dyn_checked(&a, &b);
-        overflow.expect_err("overflow should be detected");
-    }
-
     #[test]
     fn test_primitive_div_dyn_wrapping_overflow() {
         let a = Int32Array::from(vec![i32::MIN]);
@@ -3616,51 +2921,6 @@ mod tests {
         assert_eq!(e, r);
     }
 
-    #[test]
-    #[cfg(feature = "dyn_arith_dict")]
-    fn test_dictionary_div_dyn_wrapping_overflow() {
-        let mut builder =
-            PrimitiveDictionaryBuilder::<Int8Type, Int32Type>::with_capacity(1, 1);
-        builder.append(i32::MIN).unwrap();
-        let a = builder.finish();
-
-        let mut builder =
-            PrimitiveDictionaryBuilder::<Int8Type, Int32Type>::with_capacity(1, 1);
-        builder.append(-1).unwrap();
-        let b = builder.finish();
-
-        let wrapped = divide_dyn(&a, &b).unwrap();
-        let expected = Arc::new(Int32Array::from(vec![-2147483648])) as ArrayRef;
-        assert_eq!(&expected, &wrapped);
-
-        let overflow = divide_dyn_checked(&a, &b);
-        overflow.expect_err("overflow should be detected");
-    }
-
-    #[test]
-    #[cfg(feature = "dyn_arith_dict")]
-    fn test_div_dyn_opt_overflow_division_by_zero() {
-        let a = Int32Array::from(vec![i32::MIN]);
-        let b = Int32Array::from(vec![0]);
-
-        let division_by_zero = divide_dyn_opt(&a, &b);
-        let expected = Arc::new(Int32Array::from(vec![None])) as ArrayRef;
-        assert_eq!(&expected, &division_by_zero.unwrap());
-
-        let mut builder =
-            PrimitiveDictionaryBuilder::<Int8Type, Int32Type>::with_capacity(1, 1);
-        builder.append(i32::MIN).unwrap();
-        let a = builder.finish();
-
-        let mut builder =
-            PrimitiveDictionaryBuilder::<Int8Type, Int32Type>::with_capacity(1, 1);
-        builder.append(0).unwrap();
-        let b = builder.finish();
-
-        let division_by_zero = divide_dyn_opt(&a, &b);
-        assert_eq!(&expected, &division_by_zero.unwrap());
-    }
-
     #[test]
     fn test_div_scalar_dyn_opt_overflow_division_by_zero() {
         let a = Int32Array::from(vec![i32::MIN]);
@@ -3802,74 +3062,6 @@ mod tests {
         let _ = overflow.unwrap().expect_err("overflow should be detected");
     }
 
-    #[test]
-    #[cfg(feature = "dyn_arith_dict")]
-    fn test_dict_decimal() {
-        let values = Decimal128Array::from_iter_values([0, 1, 2, 3, 4, 5]);
-        let keys = Int8Array::from_iter_values([1_i8, 2, 5, 4, 3, 0]);
-        let array1 = DictionaryArray::new(keys, Arc::new(values));
-
-        let values = Decimal128Array::from_iter_values([7, -3, 4, 3, 5]);
-        let keys = Int8Array::from_iter_values([0_i8, 0, 1, 2, 3, 4]);
-        let array2 = DictionaryArray::new(keys, Arc::new(values));
-
-        let result = add_dyn(&array1, &array2).unwrap();
-        let expected =
-            Arc::new(Decimal128Array::from(vec![8, 9, 2, 8, 6, 5])) as ArrayRef;
-        assert_eq!(&result, &expected);
-
-        let result = subtract_dyn(&array1, &array2).unwrap();
-        let expected =
-            Arc::new(Decimal128Array::from(vec![-6, -5, 8, 0, 0, -5])) as ArrayRef;
-        assert_eq!(&result, &expected);
-
-        let values = Decimal256Array::from_iter_values([
-            i256::from_i128(0),
-            i256::from_i128(1),
-            i256::from_i128(2),
-            i256::from_i128(3),
-            i256::from_i128(4),
-            i256::from_i128(5),
-        ]);
-        let keys =
-            Int8Array::from(vec![Some(1_i8), None, Some(5), Some(4), Some(3), None]);
-        let array1 = DictionaryArray::new(keys, Arc::new(values));
-
-        let values = Decimal256Array::from_iter_values([
-            i256::from_i128(7),
-            i256::from_i128(-3),
-            i256::from_i128(4),
-            i256::from_i128(3),
-            i256::from_i128(5),
-        ]);
-        let keys =
-            Int8Array::from(vec![Some(0_i8), Some(0), None, Some(2), Some(3), Some(4)]);
-        let array2 = DictionaryArray::new(keys, Arc::new(values));
-
-        let result = add_dyn(&array1, &array2).unwrap();
-        let expected = Arc::new(Decimal256Array::from(vec![
-            Some(i256::from_i128(8)),
-            None,
-            None,
-            Some(i256::from_i128(8)),
-            Some(i256::from_i128(6)),
-            None,
-        ])) as ArrayRef;
-
-        assert_eq!(&result, &expected);
-
-        let result = subtract_dyn(&array1, &array2).unwrap();
-        let expected = Arc::new(Decimal256Array::from(vec![
-            Some(i256::from_i128(-6)),
-            None,
-            None,
-            Some(i256::from_i128(0)),
-            Some(i256::from_i128(0)),
-            None,
-        ])) as ArrayRef;
-        assert_eq!(&result, &expected);
-    }
-
     #[test]
     fn test_decimal_add_scalar_dyn() {
         let a = Decimal128Array::from(vec![100, 210, 320])
@@ -4047,110 +3239,6 @@ mod tests {
         );
     }
 
-    #[test]
-    #[cfg(feature = "dyn_arith_dict")]
-    fn test_decimal_multiply_fixed_point_dyn() {
-        // [123456789]
-        let a = Decimal128Array::from(vec![123456789000000000000000000])
-            .with_precision_and_scale(38, 18)
-            .unwrap();
-
-        // [10]
-        let b = Decimal128Array::from(vec![10000000000000000000])
-            .with_precision_and_scale(38, 18)
-            .unwrap();
-
-        // Avoid overflow by reducing the scale.
-        let result = multiply_fixed_point_dyn(&a, &b, 28).unwrap();
-        // [1234567890]
-        let expected = Arc::new(
-            Decimal128Array::from(vec![12345678900000000000000000000000000000])
-                .with_precision_and_scale(38, 28)
-                .unwrap(),
-        ) as ArrayRef;
-
-        assert_eq!(&expected, &result);
-        assert_eq!(
-            result.as_primitive::<Decimal128Type>().value_as_string(0),
-            "1234567890.0000000000000000000000000000"
-        );
-
-        // [123456789, 10]
-        let a = Decimal128Array::from(vec![
-            123456789000000000000000000,
-            10000000000000000000,
-        ])
-        .with_precision_and_scale(38, 18)
-        .unwrap();
-
-        // [10, 123456789, 12]
-        let b = Decimal128Array::from(vec![
-            10000000000000000000,
-            123456789000000000000000000,
-            12000000000000000000,
-        ])
-        .with_precision_and_scale(38, 18)
-        .unwrap();
-
-        let keys = Int8Array::from(vec![Some(0_i8), Some(1), Some(1), None]);
-        let array1 = DictionaryArray::new(keys, Arc::new(a));
-        let keys = Int8Array::from(vec![Some(0_i8), Some(1), Some(2), None]);
-        let array2 = DictionaryArray::new(keys, Arc::new(b));
-
-        let result = multiply_fixed_point_dyn(&array1, &array2, 28).unwrap();
-        let expected = Arc::new(
-            Decimal128Array::from(vec![
-                Some(12345678900000000000000000000000000000),
-                Some(12345678900000000000000000000000000000),
-                Some(1200000000000000000000000000000),
-                None,
-            ])
-            .with_precision_and_scale(38, 28)
-            .unwrap(),
-        ) as ArrayRef;
-
-        assert_eq!(&expected, &result);
-        assert_eq!(
-            result.as_primitive::<Decimal128Type>().value_as_string(0),
-            "1234567890.0000000000000000000000000000"
-        );
-        assert_eq!(
-            result.as_primitive::<Decimal128Type>().value_as_string(1),
-            "1234567890.0000000000000000000000000000"
-        );
-        assert_eq!(
-            result.as_primitive::<Decimal128Type>().value_as_string(2),
-            "120.0000000000000000000000000000"
-        );
-
-        // Required scale is same as the product of the input scales. Behavior is same as multiply_dyn.
-        let a = Decimal128Array::from(vec![123, 100])
-            .with_precision_and_scale(3, 2)
-            .unwrap();
-
-        let b = Decimal128Array::from(vec![100, 123, 120])
-            .with_precision_and_scale(3, 2)
-            .unwrap();
-
-        let keys = Int8Array::from(vec![Some(0_i8), Some(1), Some(1), None]);
-        let array1 = DictionaryArray::new(keys, Arc::new(a));
-        let keys = Int8Array::from(vec![Some(0_i8), Some(1), Some(2), None]);
-        let array2 = DictionaryArray::new(keys, Arc::new(b));
-
-        let result = multiply_fixed_point_dyn(&array1, &array2, 4).unwrap();
-        let expected = multiply_dyn(&array1, &array2).unwrap();
-        let expected = Arc::new(
-            expected
-                .as_any()
-                .downcast_ref::<Decimal128Array>()
-                .unwrap()
-                .clone()
-                .with_precision_and_scale(7, 4)
-                .unwrap(),
-        ) as ArrayRef;
-        assert_eq!(&expected, &result);
-    }
-
     #[test]
     fn test_timestamp_second_add_interval() {
         // timestamp second + interval year month
diff --git a/arrow/Cargo.toml b/arrow/Cargo.toml
index 998d077fa..bc126a2f4 100644
--- a/arrow/Cargo.toml
+++ b/arrow/Cargo.toml
@@ -63,7 +63,7 @@ rand = { version = "0.8", default-features = false, features = ["std", "std_rng"
 pyo3 = { version = "0.19", default-features = false, optional = true }
 
 [package.metadata.docs.rs]
-features = ["prettyprint", "ipc_compression", "dyn_cmp_dict", "dyn_arith_dict", "ffi", "pyarrow"]
+features = ["prettyprint", "ipc_compression", "dyn_cmp_dict", "ffi", "pyarrow"]
 
 [features]
 default = ["csv", "ipc", "json"]
@@ -88,9 +88,6 @@ ffi = ["arrow-schema/ffi", "arrow-data/ffi"]
 # Enable dyn-comparison of dictionary arrays with other arrays
 # Note: this does not impact comparison against scalars
 dyn_cmp_dict = ["arrow-string/dyn_cmp_dict", "arrow-ord/dyn_cmp_dict"]
-# Enable dyn-arithmetic kernels for dictionary arrays
-# Note: this does not impact arithmetic with scalars
-dyn_arith_dict = ["arrow-arith/dyn_arith_dict"]
 chrono-tz = ["arrow-array/chrono-tz"]
 
 [dev-dependencies]
diff --git a/arrow/README.md b/arrow/README.md
index 4d5206cba..adf32ff61 100644
--- a/arrow/README.md
+++ b/arrow/README.md
@@ -53,7 +53,6 @@ The `arrow` crate provides the following features which may be enabled in your `
 - `ffi` - bindings for the Arrow C [C Data Interface](https://arrow.apache.org/docs/format/CDataInterface.html)
 - `pyarrow` - bindings for pyo3 to call arrow-rs from python
 - `dyn_cmp_dict` - enables comparison of dictionary arrays within dyn comparison kernels
-- `dyn_arith_dict` - enables arithmetic on dictionary arrays within dyn arithmetic kernels
 
 ## Arrow Feature Status