You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ap...@apache.org on 2019/02/14 20:20:28 UTC

[arrow] branch master updated: ARROW-4563: [Python] Validate decimal128() precision input

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

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


The following commit(s) were added to refs/heads/master by this push:
     new b9819e8  ARROW-4563: [Python] Validate decimal128() precision input
b9819e8 is described below

commit b9819e8e705932f28cb2f7b0115286bbd2bdefa9
Author: Antoine Pitrou <an...@python.org>
AuthorDate: Thu Feb 14 21:20:16 2019 +0100

    ARROW-4563: [Python] Validate decimal128() precision input
    
    Also add a debug check on the C++ side.
    
    Author: Antoine Pitrou <an...@python.org>
    
    Closes #3647 from pitrou/ARROW-4563-py-validate-decimal128-inputs and squashes the following commits:
    
    5a4cd6ae <Antoine Pitrou> ARROW-4563:  Validate decimal128() precision input
---
 cpp/src/arrow/type.cc                      | 9 +++++++++
 cpp/src/arrow/type.h                       | 3 +--
 cpp/src/gandiva/expression_registry.cc     | 2 +-
 cpp/src/gandiva/function_registry_common.h | 2 +-
 python/pyarrow/tests/test_types.py         | 8 ++++++++
 python/pyarrow/types.pxi                   | 2 ++
 6 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/cpp/src/arrow/type.cc b/cpp/src/arrow/type.cc
index 15f353d..79ad7c1 100644
--- a/cpp/src/arrow/type.cc
+++ b/cpp/src/arrow/type.cc
@@ -293,6 +293,15 @@ int StructType::GetChildIndex(const std::string& name) const {
 }
 
 // ----------------------------------------------------------------------
+// Decimal128 type
+
+Decimal128Type::Decimal128Type(int32_t precision, int32_t scale)
+    : DecimalType(16, precision, scale) {
+  DCHECK_GE(precision, 1);
+  DCHECK_LE(precision, 38);
+}
+
+// ----------------------------------------------------------------------
 // DictionaryType
 
 DictionaryType::DictionaryType(const std::shared_ptr<DataType>& index_type,
diff --git a/cpp/src/arrow/type.h b/cpp/src/arrow/type.h
index 752fc85..3d01b5a 100644
--- a/cpp/src/arrow/type.h
+++ b/cpp/src/arrow/type.h
@@ -550,8 +550,7 @@ class ARROW_EXPORT Decimal128Type : public DecimalType {
  public:
   static constexpr Type::type type_id = Type::DECIMAL;
 
-  explicit Decimal128Type(int32_t precision, int32_t scale)
-      : DecimalType(16, precision, scale) {}
+  explicit Decimal128Type(int32_t precision, int32_t scale);
 
   Status Accept(TypeVisitor* visitor) const override;
   std::string ToString() const override;
diff --git a/cpp/src/gandiva/expression_registry.cc b/cpp/src/gandiva/expression_registry.cc
index 1a087c9..6dff6bd 100644
--- a/cpp/src/gandiva/expression_registry.cc
+++ b/cpp/src/gandiva/expression_registry.cc
@@ -137,7 +137,7 @@ void ExpressionRegistry::AddArrowTypesToVector(arrow::Type::type& type,
       vector.push_back(arrow::null());
       break;
     case arrow::Type::type::DECIMAL:
-      vector.push_back(arrow::decimal(0, 0));
+      vector.push_back(arrow::decimal(38, 0));
       break;
     case arrow::Type::type::FIXED_SIZE_BINARY:
     case arrow::Type::type::MAP:
diff --git a/cpp/src/gandiva/function_registry_common.h b/cpp/src/gandiva/function_registry_common.h
index 3ae065a..3105555 100644
--- a/cpp/src/gandiva/function_registry_common.h
+++ b/cpp/src/gandiva/function_registry_common.h
@@ -53,7 +53,7 @@ inline DataTypePtr time32() { return arrow::time32(arrow::TimeUnit::MILLI); }
 inline DataTypePtr time64() { return arrow::time64(arrow::TimeUnit::MICRO); }
 
 inline DataTypePtr timestamp() { return arrow::timestamp(arrow::TimeUnit::MILLI); }
-inline DataTypePtr decimal128() { return arrow::decimal(0, 0); }
+inline DataTypePtr decimal128() { return arrow::decimal(38, 0); }
 
 struct KeyHash {
   std::size_t operator()(const FunctionSignature* k) const { return k->Hash(); }
diff --git a/python/pyarrow/tests/test_types.py b/python/pyarrow/tests/test_types.py
index 729c76e..11c0cca 100644
--- a/python/pyarrow/tests/test_types.py
+++ b/python/pyarrow/tests/test_types.py
@@ -402,6 +402,14 @@ def test_decimal_properties():
     assert ty.scale == 4
 
 
+def test_decimal_overflow():
+    pa.decimal128(1, 0)
+    pa.decimal128(38, 0)
+    for i in (0, -1, 39):
+        with pytest.raises(ValueError):
+            pa.decimal128(39, 0)
+
+
 def test_type_equality_operators():
     many_types = get_many_types()
     non_pyarrow = ('foo', 16, {'s', 'e', 't'})
diff --git a/python/pyarrow/types.pxi b/python/pyarrow/types.pxi
index 7c6aec3..72f62b3 100644
--- a/python/pyarrow/types.pxi
+++ b/python/pyarrow/types.pxi
@@ -1321,6 +1321,8 @@ cpdef DataType decimal128(int precision, int scale=0):
     decimal_type : Decimal128Type
     """
     cdef shared_ptr[CDataType] decimal_type
+    if precision < 1 or precision > 38:
+        raise ValueError("precision should be between 1 and 38")
     decimal_type.reset(new CDecimal128Type(precision, scale))
     return pyarrow_wrap_data_type(decimal_type)