1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements.  See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership.  The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License.  You may obtain a copy of the License at
8 //
9 //   http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied.  See the License for the
15 // specific language governing permissions and limitations
16 // under the License.
17 
18 #pragma once
19 
20 #include <string>
21 
22 #include "arrow/python/visibility.h"
23 #include "arrow/type.h"
24 
25 namespace arrow {
26 
27 class Decimal128;
28 class Decimal256;
29 
30 namespace py {
31 
32 class OwnedRef;
33 
34 //
35 // Python Decimal support
36 //
37 
38 namespace internal {
39 
40 // \brief Import the Python Decimal type
41 ARROW_PYTHON_EXPORT
42 Status ImportDecimalType(OwnedRef* decimal_type);
43 
44 // \brief Convert a Python Decimal object to a C++ string
45 // \param[in] python_decimal A Python decimal.Decimal instance
46 // \param[out] The string representation of the Python Decimal instance
47 // \return The status of the operation
48 ARROW_PYTHON_EXPORT
49 Status PythonDecimalToString(PyObject* python_decimal, std::string* out);
50 
51 // \brief Convert a C++ std::string to a Python Decimal instance
52 // \param[in] decimal_constructor The decimal type object
53 // \param[in] decimal_string A decimal string
54 // \return An instance of decimal.Decimal
55 ARROW_PYTHON_EXPORT
56 PyObject* DecimalFromString(PyObject* decimal_constructor,
57                             const std::string& decimal_string);
58 
59 // \brief Convert a Python decimal to an Arrow Decimal128 object
60 // \param[in] python_decimal A Python decimal.Decimal instance
61 // \param[in] arrow_type An instance of arrow::DecimalType
62 // \param[out] out A pointer to a Decimal128
63 // \return The status of the operation
64 ARROW_PYTHON_EXPORT
65 Status DecimalFromPythonDecimal(PyObject* python_decimal, const DecimalType& arrow_type,
66                                 Decimal128* out);
67 
68 // \brief Convert a Python object to an Arrow Decimal128 object
69 // \param[in] python_decimal A Python int or decimal.Decimal instance
70 // \param[in] arrow_type An instance of arrow::DecimalType
71 // \param[out] out A pointer to a Decimal128
72 // \return The status of the operation
73 ARROW_PYTHON_EXPORT
74 Status DecimalFromPyObject(PyObject* obj, const DecimalType& arrow_type, Decimal128* out);
75 
76 // \brief Convert a Python decimal to an Arrow Decimal256 object
77 // \param[in] python_decimal A Python decimal.Decimal instance
78 // \param[in] arrow_type An instance of arrow::DecimalType
79 // \param[out] out A pointer to a Decimal256
80 // \return The status of the operation
81 ARROW_PYTHON_EXPORT
82 Status DecimalFromPythonDecimal(PyObject* python_decimal, const DecimalType& arrow_type,
83                                 Decimal256* out);
84 
85 // \brief Convert a Python object to an Arrow Decimal256 object
86 // \param[in] python_decimal A Python int or decimal.Decimal instance
87 // \param[in] arrow_type An instance of arrow::DecimalType
88 // \param[out] out A pointer to a Decimal256
89 // \return The status of the operation
90 ARROW_PYTHON_EXPORT
91 Status DecimalFromPyObject(PyObject* obj, const DecimalType& arrow_type, Decimal256* out);
92 
93 // \brief Check whether obj is an instance of Decimal
94 ARROW_PYTHON_EXPORT
95 bool PyDecimal_Check(PyObject* obj);
96 
97 // \brief Check whether obj is nan. This function will abort the program if the argument
98 // is not a Decimal instance
99 ARROW_PYTHON_EXPORT
100 bool PyDecimal_ISNAN(PyObject* obj);
101 
102 // \brief Helper class to track and update the precision and scale of a decimal
103 class ARROW_PYTHON_EXPORT DecimalMetadata {
104  public:
105   DecimalMetadata();
106   DecimalMetadata(int32_t precision, int32_t scale);
107 
108   // \brief Adjust the precision and scale of a decimal type given a new precision and a
109   // new scale \param[in] suggested_precision A candidate precision \param[in]
110   // suggested_scale A candidate scale \return The status of the operation
111   Status Update(int32_t suggested_precision, int32_t suggested_scale);
112 
113   // \brief A convenient interface for updating the precision and scale based on a Python
114   // Decimal object \param object A Python Decimal object \return The status of the
115   // operation
116   Status Update(PyObject* object);
117 
precision()118   int32_t precision() const { return precision_; }
scale()119   int32_t scale() const { return scale_; }
120 
121  private:
122   int32_t precision_;
123   int32_t scale_;
124 };
125 
126 }  // namespace internal
127 }  // namespace py
128 }  // namespace arrow
129