Skip to content

Commit 5a4cd6a

Browse files
committed
ARROW-4563: [Python] Validate decimal128() precision input
Also add a debug check on the C++ side.
1 parent 49c70cc commit 5a4cd6a

File tree

6 files changed

+22
-4
lines changed

6 files changed

+22
-4
lines changed

cpp/src/arrow/type.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,15 @@ int StructType::GetChildIndex(const std::string& name) const {
292292
return GetFieldIndex(name);
293293
}
294294

295+
// ----------------------------------------------------------------------
296+
// Decimal128 type
297+
298+
Decimal128Type::Decimal128Type(int32_t precision, int32_t scale)
299+
: DecimalType(16, precision, scale) {
300+
DCHECK_GE(precision, 1);
301+
DCHECK_LE(precision, 38);
302+
}
303+
295304
// ----------------------------------------------------------------------
296305
// DictionaryType
297306

cpp/src/arrow/type.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -550,8 +550,7 @@ class ARROW_EXPORT Decimal128Type : public DecimalType {
550550
public:
551551
static constexpr Type::type type_id = Type::DECIMAL;
552552

553-
explicit Decimal128Type(int32_t precision, int32_t scale)
554-
: DecimalType(16, precision, scale) {}
553+
explicit Decimal128Type(int32_t precision, int32_t scale);
555554

556555
Status Accept(TypeVisitor* visitor) const override;
557556
std::string ToString() const override;

cpp/src/gandiva/expression_registry.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ void ExpressionRegistry::AddArrowTypesToVector(arrow::Type::type& type,
137137
vector.push_back(arrow::null());
138138
break;
139139
case arrow::Type::type::DECIMAL:
140-
vector.push_back(arrow::decimal(0, 0));
140+
vector.push_back(arrow::decimal(38, 0));
141141
break;
142142
case arrow::Type::type::FIXED_SIZE_BINARY:
143143
case arrow::Type::type::MAP:

cpp/src/gandiva/function_registry_common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ inline DataTypePtr time32() { return arrow::time32(arrow::TimeUnit::MILLI); }
5353
inline DataTypePtr time64() { return arrow::time64(arrow::TimeUnit::MICRO); }
5454

5555
inline DataTypePtr timestamp() { return arrow::timestamp(arrow::TimeUnit::MILLI); }
56-
inline DataTypePtr decimal128() { return arrow::decimal(0, 0); }
56+
inline DataTypePtr decimal128() { return arrow::decimal(38, 0); }
5757

5858
struct KeyHash {
5959
std::size_t operator()(const FunctionSignature* k) const { return k->Hash(); }

python/pyarrow/tests/test_types.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,14 @@ def test_decimal_properties():
402402
assert ty.scale == 4
403403

404404

405+
def test_decimal_overflow():
406+
pa.decimal128(1, 0)
407+
pa.decimal128(38, 0)
408+
for i in (0, -1, 39):
409+
with pytest.raises(ValueError):
410+
pa.decimal128(39, 0)
411+
412+
405413
def test_type_equality_operators():
406414
many_types = get_many_types()
407415
non_pyarrow = ('foo', 16, {'s', 'e', 't'})

python/pyarrow/types.pxi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,6 +1321,8 @@ cpdef DataType decimal128(int precision, int scale=0):
13211321
decimal_type : Decimal128Type
13221322
"""
13231323
cdef shared_ptr[CDataType] decimal_type
1324+
if precision < 1 or precision > 38:
1325+
raise ValueError("precision should be between 1 and 38")
13241326
decimal_type.reset(new CDecimal128Type(precision, scale))
13251327
return pyarrow_wrap_data_type(decimal_type)
13261328

0 commit comments

Comments
 (0)