code: def _get_decimal_type(lhs_dtype, rhs_dtype, op):
      """
      Returns the resulting decimal type after calculating
      precision & scale when performing the binary operation
      `op` for the given dtypes.
  
      For precision & scale calculations see : https://docs.microsoft.com/en-us/sql/t-sql/data-types/precision-scale-and-length-transact-sql
      """  # noqa: E501
  
      # This should at some point be hooked up to libcudf's
      # binary_operation_fixed_point_scale
  
      p1, p2 = lhs_dtype.precision, rhs_dtype.precision
      s1, s2 = lhs_dtype.scale, rhs_dtype.scale
  
      if op in {"__add__", "__sub__"}:
          scale = max(s1, s2)
          precision = scale + max(p1 - s1, p2 - s2) + 1
          if precision > Decimal128Dtype.MAX_PRECISION:
              precision = Decimal128Dtype.MAX_PRECISION
              scale = Decimal128Dtype.MAX_PRECISION - max(
                  p1 - s1, p2 - s2
              )
      elif op in {"__mul__", "__div__"}:
          if op == "__mul__":
              scale = s1 + s2
              precision = p1 + p2 + 1
          else:
              scale = max(6, s1 + p2 + 1)
              precision = p1 - s1 + s2 + scale
          if precision > Decimal128Dtype.MAX_PRECISION:
              integral = precision - scale
              if integral < 32:
                  scale = min(
                      scale, Decimal128Dtype.MAX_PRECISION - integral
                  )
              elif scale > 6 and integral > 32:
                  scale = 6
              precision = Decimal128Dtype.MAX_PRECISION
      else:
          raise NotImplementedError()
  
      try:
          if isinstance(lhs_dtype, type(rhs_dtype)):
              # SCENARIO 1: If `lhs_dtype` & `rhs_dtype` are same, then try to
              # see if `precision` & `scale` can be fit into this type.
              return lhs_dtype.__class__(
                  precision=precision, scale=scale
              )
          else:
              # SCENARIO 2: If `lhs_dtype` & `rhs_dtype` are of different dtypes,
              # then try to see if `precision` & `scale` can be fit into the type
              # with greater MAX_PRECISION (i.e., the bigger dtype).
              if lhs_dtype.MAX_PRECISION >= rhs_dtype.MAX_PRECISION:
                  return lhs_dtype.__class__(
                      precision=precision, scale=scale
                  )
              else:
                  return rhs_dtype.__class__(
                      precision=precision, scale=scale
                  )
      except ValueError:
          # Call to _validate fails, which means we need
          # to goto SCENARIO 3.
          pass
  
      # SCENARIO 3: If either of the above two scenarios fail, then get the
      # MAX_PRECISION of `lhs_dtype` & `rhs_dtype` so that we can only check
      # and return a dtype that is greater than or equal to input dtype that
      # can fit `precision` & `scale`.
      max_precision = max(
          lhs_dtype.MAX_PRECISION, rhs_dtype.MAX_PRECISION
      )
      for decimal_type in (
          Decimal32Dtype,
          Decimal64Dtype,
          Decimal128Dtype,
      ):
          if decimal_type.MAX_PRECISION >= max_precision:
              try:
                  return decimal_type(precision=precision, scale=scale)
              except ValueError:
                  # Call to _validate fails, which means we need
                  # to try the next dtype
                  continue
  
      # if we've reached this point, we cannot create a decimal type without
      # overflow; raise an informative error
      raise ValueError(
          f"Performing {op} between columns of type {repr(lhs_dtype)} and "
          f"{repr(rhs_dtype)} would result in overflow"
      )
  
imports: from __future__ import annotations
  import warnings
  from decimal import Decimal
  from typing import Any, Optional, Sequence, Union, cast
  import cupy
  import numpy
  import pyarrow
  from typing_extensions import Self
  import cudf
  from cudf import _lib
  from cudf._lib.strings.convert.convert_fixed_point import from_decimal
  from cudf._typing import ColumnBinaryOperand, Dtype
  from cudf.api.types import is_integer_dtype, is_scalar
  from cudf.core.buffer import as_buffer
  from cudf.core.column import ColumnBase
  from cudf.core.dtypes import Decimal32Dtype, Decimal64Dtype, Decimal128Dtype, DecimalDtype
  from cudf.core.mixins import BinaryOperand
  from cudf.utils.utils import pa_mask_buffer_to_mask
  from .numerical_base import NumericalBaseColumn
label_desc: Use image node_id 1 for calling a global function with example usage: _get_decimal_type(lhs_dtype, rhs_dtype, op) and returns: lhs_dtype, lhs_dtype, rhs_dtype, decimal_type