MCPcopy Create free account
hub / github.com/apache/arrow / InferDecimalPrecisionAndScale

Function InferDecimalPrecisionAndScale

python/pyarrow/src/arrow/python/decimal.cc:49–90  ·  view source on GitHub ↗

\brief Infer the precision and scale of a Python decimal.Decimal instance \param python_decimal[in] An instance of decimal.Decimal \param precision[out] The value of the inferred precision \param scale[out] The value of the inferred scale \return The status of the operation

Source from the content-addressed store, hash-verified

47// \param scale[out] The value of the inferred scale
48// \return The status of the operation
49static Status InferDecimalPrecisionAndScale(PyObject* python_decimal, int32_t* precision,
50 int32_t* scale) {
51 ARROW_DCHECK_NE(python_decimal, NULLPTR);
52 ARROW_DCHECK_NE(precision, NULLPTR);
53 ARROW_DCHECK_NE(scale, NULLPTR);
54
55 // TODO(phillipc): Make sure we perform PyDecimal_Check(python_decimal) as a
56 // ARROW_DCHECK
57 OwnedRef as_tuple(PyObject_CallMethod(python_decimal, const_cast<char*>("as_tuple"),
58 const_cast<char*>("")));
59 RETURN_IF_PYERROR();
60 ARROW_DCHECK(PyTuple_Check(as_tuple.obj()));
61
62 OwnedRef digits(PyObject_GetAttrString(as_tuple.obj(), "digits"));
63 RETURN_IF_PYERROR();
64 ARROW_DCHECK(PyTuple_Check(digits.obj()));
65
66 const auto num_digits = static_cast<int32_t>(PyTuple_Size(digits.obj()));
67 RETURN_IF_PYERROR();
68
69 OwnedRef py_exponent(PyObject_GetAttrString(as_tuple.obj(), "exponent"));
70 RETURN_IF_PYERROR();
71 ARROW_DCHECK(IsPyInteger(py_exponent.obj()));
72
73 const auto exponent = static_cast<int32_t>(PyLong_AsLong(py_exponent.obj()));
74 RETURN_IF_PYERROR();
75
76 if (exponent < 0) {
77 // If exponent > num_digits, we have a number with leading zeros
78 // such as 0.01234. Ensure we have enough precision for leading zeros
79 // (which are not included in num_digits).
80 *precision = std::max(num_digits, -exponent);
81 *scale = -exponent;
82 } else {
83 // Trailing zeros are not included in num_digits, need to add to precision.
84 // Note we don't generate negative scales as they are poorly supported
85 // in non-Arrow systems.
86 *precision = num_digits + exponent;
87 *scale = 0;
88 }
89 return Status::OK();
90}
91
92PyObject* DecimalFromString(PyObject* decimal_constructor,
93 const std::string& decimal_string) {

Callers 1

UpdateMethod · 0.85

Calls 2

IsPyIntegerFunction · 0.85
OKFunction · 0.50

Tested by

no test coverage detected