mrkn commented on a change in pull request #8919:
URL: https://github.com/apache/arrow/pull/8919#discussion_r543067083
##########
File path: c_glib/arrow-glib/basic-data-type.cpp
##########
@@ -92,9 +92,11 @@ G_BEGIN_DECLS
* #GArrowTime64DataType is a class for the number of microseconds or
* nanoseconds since midnight in 64-bit signed integer data type.
*
- * #GArrowDecimalDataType is a base class for decimal data type.
+ * #GArrowDecimalDataType is a base class for decimal data types.
*
* #GArrowDecimal128DataType is a class for 128-bit decimal data type.
+ *
+ * #GArrowDecimal256DataType is a class for 256-bit decimal data type.
Review comment:
I guess it is better to put "the" before "256-bit decimal data type" and
other data types.
##########
File path: ruby/red-arrow/lib/arrow/decimal256.rb
##########
@@ -0,0 +1,42 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+module Arrow
+ class Decimal256
+ alias_method :to_s_raw, :to_s
+
+ # @overload to_s
+ #
+ # @return [String]
+ # The string representation of the decimal.
+ #
+ # @overload to_s(scale)
+ #
+ # @param scale [Integer] The scale of the decimal.
+ # @return [String]
+ # The string representation of the decimal including the scale.
+ #
+ # @since 3.0.0
+ def to_s(scale=nil)
+ if scale
+ to_string_scale(scale)
+ else
+ to_s_raw
+ end
+ end
+ end
+end
Review comment:
I guess `Arrow::Decimal256#abs` is destructive. Should we rename it to
`Arrow::Decimal256#abs!`?
##########
File path: ruby/red-arrow/lib/arrow/array-builder.rb
##########
@@ -115,6 +115,17 @@ def detect_builder_info(value, builder_info)
builder: Date32ArrayBuilder.new,
detected: true,
}
+ when BigDecimal
+ if value.precs[0] > Arrow::Decimal128DataType::MAX_PRECISION
Review comment:
Unfortunately, `value.prec[0]` does not mean the number of digits that
`value` has.
It just means the number of digits can be contained in the internal buffer
of `value`.
Now we should calculate the number of digits of a BigDecimal from the result
of `value.to_s("F")`.
I will fix this issue in bigdecimal.
##########
File path: c_glib/arrow-glib/decimal.cpp
##########
@@ -0,0 +1,1026 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <arrow-glib/decimal.hpp>
+#include <arrow-glib/error.hpp>
+
+template <typename Decimal>
+struct DecimalConverter {
+};
+
+template <>
+struct DecimalConverter<arrow::Decimal128> {
+ using ArrowType = arrow::Decimal128;
+ using GArrowType = GArrowDecimal128;
+
+ GArrowType *
+ new_raw(std::shared_ptr<ArrowType> *arrow_decimal128)
+ {
+ return garrow_decimal128_new_raw(arrow_decimal128);
+ }
+
+ std::shared_ptr<ArrowType>
+ get_raw(GArrowType *decimal128)
+ {
+ return garrow_decimal128_get_raw(decimal128);
+ }
+};
+
+template <>
+struct DecimalConverter<arrow::Decimal256> {
+ using ArrowType = arrow::Decimal256;
+ using GArrowType = GArrowDecimal256;
+
+ GArrowType *
+ new_raw(std::shared_ptr<ArrowType> *arrow_decimal256) {
+ return garrow_decimal256_new_raw(arrow_decimal256);
+ }
+
+ std::shared_ptr<ArrowType>
+ get_raw(GArrowType *decimal256) {
+ return garrow_decimal256_get_raw(decimal256);
+ }
+};
+
+template <typename Decimal>
+typename DecimalConverter<Decimal>::GArrowType *
+garrow_decimal_new_string(const gchar *data)
+{
+ auto arrow_decimal = std::make_shared<Decimal>(data);
+ DecimalConverter<Decimal> converter;
+ return converter.new_raw(&arrow_decimal);
+}
+
+template <typename Decimal>
+typename DecimalConverter<Decimal>::GArrowType *
+garrow_decimal_new_integer(const gint64 data)
+{
+ auto arrow_decimal = std::make_shared<Decimal>(data);
+ DecimalConverter<Decimal> converter;
+ return converter.new_raw(&arrow_decimal);
+}
+
+template <typename Decimal>
+gboolean
+garrow_decimal_equal(typename DecimalConverter<Decimal>::GArrowType *decimal,
+ typename DecimalConverter<Decimal>::GArrowType
*other_decimal)
+{
+ DecimalConverter<Decimal> converter;
+ const auto arrow_decimal = converter.get_raw(decimal);
+ const auto arrow_other_decimal = converter.get_raw(other_decimal);
+ return *arrow_decimal == *arrow_other_decimal;
+}
+
+template <typename Decimal>
+gboolean
+garrow_decimal_not_equal(typename DecimalConverter<Decimal>::GArrowType
*decimal,
+ typename DecimalConverter<Decimal>::GArrowType
*other_decimal)
+{
+ DecimalConverter<Decimal> converter;
+ const auto arrow_decimal = converter.get_raw(decimal);
+ const auto arrow_other_decimal = converter.get_raw(other_decimal);
+ return *arrow_decimal != *arrow_other_decimal;
+}
+
+template <typename Decimal>
+gboolean
+garrow_decimal_less_than(typename DecimalConverter<Decimal>::GArrowType
*decimal,
+ typename DecimalConverter<Decimal>::GArrowType
*other_decimal)
+{
+ DecimalConverter<Decimal> converter;
+ const auto arrow_decimal = converter.get_raw(decimal);
+ const auto arrow_other_decimal = converter.get_raw(other_decimal);
+ return *arrow_decimal < *arrow_other_decimal;
+}
+
+template <typename Decimal>
+gboolean
+garrow_decimal_less_than_or_equal(typename
DecimalConverter<Decimal>::GArrowType *decimal,
+ typename
DecimalConverter<Decimal>::GArrowType *other_decimal)
+{
+ DecimalConverter<Decimal> converter;
+ const auto arrow_decimal = converter.get_raw(decimal);
+ const auto arrow_other_decimal = converter.get_raw(other_decimal);
+ return *arrow_decimal <= *arrow_other_decimal;
+}
+
+template <typename Decimal>
+gboolean
+garrow_decimal_greater_than(typename DecimalConverter<Decimal>::GArrowType
*decimal,
+ typename DecimalConverter<Decimal>::GArrowType
*other_decimal)
+{
+ DecimalConverter<Decimal> converter;
+ const auto arrow_decimal = converter.get_raw(decimal);
+ const auto arrow_other_decimal = converter.get_raw(other_decimal);
+ return *arrow_decimal > *arrow_other_decimal;
+}
+
+template <typename Decimal>
+gboolean
+garrow_decimal_greater_than_or_equal(typename
DecimalConverter<Decimal>::GArrowType *decimal,
+ typename
DecimalConverter<Decimal>::GArrowType *other_decimal)
+{
+ DecimalConverter<Decimal> converter;
+ const auto arrow_decimal = converter.get_raw(decimal);
+ const auto arrow_other_decimal = converter.get_raw(other_decimal);
+ return *arrow_decimal >= *arrow_other_decimal;
+}
+
+template <typename Decimal>
+gchar *
+garrow_decimal_to_string_scale(typename DecimalConverter<Decimal>::GArrowType
*decimal,
+ gint32 scale)
+{
+ DecimalConverter<Decimal> converter;
+ const auto arrow_decimal = converter.get_raw(decimal);
+ return g_strdup(arrow_decimal->ToString(scale).c_str());
+}
+
+template <typename Decimal>
+gchar *
+garrow_decimal_to_string(typename DecimalConverter<Decimal>::GArrowType
*decimal)
+{
+ DecimalConverter<Decimal> converter;
+ const auto arrow_decimal = converter.get_raw(decimal);
+ return g_strdup(arrow_decimal->ToIntegerString().c_str());
+}
+
+template <typename Decimal>
+void
+garrow_decimal_abs(typename DecimalConverter<Decimal>::GArrowType *decimal)
+{
+ DecimalConverter<Decimal> converter;
+ auto arrow_decimal = converter.get_raw(decimal);
+ arrow_decimal->Abs();
+}
+
+template <typename Decimal>
+void
+garrow_decimal_negate(typename DecimalConverter<Decimal>::GArrowType *decimal)
+{
+ DecimalConverter<Decimal> converter;
+ auto arrow_decimal = converter.get_raw(decimal);
+ arrow_decimal->Negate();
+}
+
+template <typename Decimal>
+typename DecimalConverter<Decimal>::GArrowType *
+garrow_decimal_plus(typename DecimalConverter<Decimal>::GArrowType *left,
+ typename DecimalConverter<Decimal>::GArrowType *right)
+{
+ DecimalConverter<Decimal> converter;
+ auto arrow_left = converter.get_raw(left);
+ auto arrow_right = converter.get_raw(right);
+ auto arrow_decimal = std::make_shared<Decimal>(*arrow_left + *arrow_right);
+ return converter.new_raw(&arrow_decimal);
+}
+
+template <typename Decimal>
+typename DecimalConverter<Decimal>::GArrowType *
+garrow_decimal_minus(typename DecimalConverter<Decimal>::GArrowType *left,
+ typename DecimalConverter<Decimal>::GArrowType *right)
+{
+ DecimalConverter<Decimal> converter;
+ auto arrow_left = converter.get_raw(left);
+ auto arrow_right = converter.get_raw(right);
+ auto arrow_decimal = std::make_shared<Decimal>(*arrow_left - *arrow_right);
+ return converter.new_raw(&arrow_decimal);
+}
+
+template <typename Decimal>
+typename DecimalConverter<Decimal>::GArrowType *
+garrow_decimal_multiply(typename DecimalConverter<Decimal>::GArrowType *left,
+ typename DecimalConverter<Decimal>::GArrowType *right)
+{
+ DecimalConverter<Decimal> converter;
+ auto arrow_left = converter.get_raw(left);
+ auto arrow_right = converter.get_raw(right);
+ auto arrow_decimal = std::make_shared<Decimal>(*arrow_left * *arrow_right);
+ return converter.new_raw(&arrow_decimal);
+}
+
+template <typename Decimal>
+typename DecimalConverter<Decimal>::GArrowType *
+garrow_decimal_divide(typename DecimalConverter<Decimal>::GArrowType *left,
+ typename DecimalConverter<Decimal>::GArrowType *right,
+ typename DecimalConverter<Decimal>::GArrowType
**remainder,
+ GError **error,
+ const gchar *tag)
+{
+ DecimalConverter<Decimal> converter;
+ auto arrow_left = converter.get_raw(left);
+ auto arrow_right = converter.get_raw(right);
+ auto arrow_result = arrow_left->Divide(*arrow_right);
+ if (garrow::check(error, arrow_result, tag)) {
+ Decimal arrow_quotient_raw;
+ Decimal arrow_remainder_raw;
+ std::tie(arrow_quotient_raw, arrow_remainder_raw) = *arrow_result;
+ if (remainder) {
+ auto arrow_remainder = std::make_shared<Decimal>(arrow_remainder_raw);
+ *remainder = converter.new_raw(&arrow_remainder);
+ }
+ auto arrow_quotient = std::make_shared<Decimal>(arrow_quotient_raw);
+ return converter.new_raw(&arrow_quotient);
+ } else {
+ if (remainder) {
+ *remainder = NULL;
+ }
+ return NULL;
+ }
+}
+
+template <typename Decimal>
+typename DecimalConverter<Decimal>::GArrowType *
+garrow_decimal_rescale(typename DecimalConverter<Decimal>::GArrowType *decimal,
+ gint32 original_scale,
+ gint32 new_scale,
+ GError **error,
+ const gchar *tag)
+{
+ DecimalConverter<Decimal> converter;
+ auto arrow_decimal = converter.get_raw(decimal);
+ auto arrow_result = arrow_decimal->Rescale(original_scale, new_scale);
+ if (garrow::check(error, arrow_result, tag)) {
+ auto arrow_rescaled_decimal = std::make_shared<Decimal>(*arrow_result);
+ return converter.new_raw(&arrow_rescaled_decimal);
+ } else {
+ return NULL;
+ }
+}
+
+
+G_BEGIN_DECLS
+
+/**
+ * SECTION: decimal
+ * @section_id: decimal
+ * @title: 128-bit and 256-bit decimal classes
+ * @include: arrow-glib/arrow-glib.h
+ *
+ * #GArrowDecimal128 is a 128-bit decimal class.
+ *
+ * #GArrowDecimal256 is a 256-bit decimal class.
+ *
+ * Since: 0.10.0
+ */
+
+typedef struct GArrowDecimal128Private_ {
+ std::shared_ptr<arrow::Decimal128> decimal128;
+} GArrowDecimal128Private;
+
+enum {
+ PROP_DECIMAL128 = 1
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE(GArrowDecimal128,
+ garrow_decimal128,
+ G_TYPE_OBJECT)
+
+#define GARROW_DECIMAL128_GET_PRIVATE(obj) \
+ static_cast<GArrowDecimal128Private *>( \
+ garrow_decimal128_get_instance_private( \
+ GARROW_DECIMAL128(obj)))
+
+static void
+garrow_decimal128_finalize(GObject *object)
+{
+ auto priv = GARROW_DECIMAL128_GET_PRIVATE(object);
+
+ priv->decimal128.~shared_ptr();
+
+ G_OBJECT_CLASS(garrow_decimal128_parent_class)->finalize(object);
+}
+
+static void
+garrow_decimal128_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ auto priv = GARROW_DECIMAL128_GET_PRIVATE(object);
+
+ switch (prop_id) {
+ case PROP_DECIMAL128:
+ priv->decimal128 =
+ *static_cast<std::shared_ptr<arrow::Decimal128>
*>(g_value_get_pointer(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+garrow_decimal128_init(GArrowDecimal128 *object)
+{
+ auto priv = GARROW_DECIMAL128_GET_PRIVATE(object);
+ new(&priv->decimal128) std::shared_ptr<arrow::Decimal128>;
+}
+
+static void
+garrow_decimal128_class_init(GArrowDecimal128Class *klass)
+{
+ GParamSpec *spec;
+
+ auto gobject_class = G_OBJECT_CLASS(klass);
+
+ gobject_class->finalize = garrow_decimal128_finalize;
+ gobject_class->set_property = garrow_decimal128_set_property;
+
+ spec = g_param_spec_pointer("decimal128",
+ "Decimal128",
+ "The raw std::shared<arrow::Decimal128> *",
+ static_cast<GParamFlags>(G_PARAM_WRITABLE |
+
G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property(gobject_class, PROP_DECIMAL128, spec);
+}
+
+/**
+ * garrow_decimal128_new_string:
+ * @data: The data of the decimal.
+ *
+ * Returns: A newly created #GArrowDecimal128.
+ *
+ * Since: 0.10.0
+ */
+GArrowDecimal128 *
+garrow_decimal128_new_string(const gchar *data)
+{
+ return garrow_decimal_new_string<arrow::Decimal128>(data);
+}
+
+/**
+ * garrow_decimal128_new_integer:
+ * @data: The data of the decimal.
+ *
+ * Returns: A newly created #GArrowDecimal128.
+ *
+ * Since: 0.10.0
+ */
+GArrowDecimal128 *
+garrow_decimal128_new_integer(const gint64 data)
+{
+ return garrow_decimal_new_integer<arrow::Decimal128>(data);
+}
+
+/**
+ * garrow_decimal128_equal:
+ * @decimal: A #GArrowDecimal128.
+ * @other_decimal: A #GArrowDecimal128 to be compared.
+ *
+ * Returns: %TRUE if the decimal is equal to the other decimal, %FALSE
+ * otherwise.
+ *
+ * Since: 0.12.0
+ */
+gboolean
+garrow_decimal128_equal(GArrowDecimal128 *decimal,
+ GArrowDecimal128 *other_decimal)
+{
+ return garrow_decimal_equal<arrow::Decimal128>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal128_not_equal:
+ * @decimal: A #GArrowDecimal128.
+ * @other_decimal: A #GArrowDecimal128 to be compared.
+ *
+ * Returns: %TRUE if the decimal isn't equal to the other decimal,
+ * %FALSE otherwise.
+ *
+ * Since: 0.12.0
+ */
+gboolean
+garrow_decimal128_not_equal(GArrowDecimal128 *decimal,
+ GArrowDecimal128 *other_decimal)
+{
+ return garrow_decimal_not_equal<arrow::Decimal128>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal128_less_than:
+ * @decimal: A #GArrowDecimal128.
+ * @other_decimal: A #GArrowDecimal128 to be compared.
+ *
+ * Returns: %TRUE if the decimal is less than the other decimal,
+ * %FALSE otherwise.
+ *
+ * Since: 0.12.0
+ */
+gboolean
+garrow_decimal128_less_than(GArrowDecimal128 *decimal,
+ GArrowDecimal128 *other_decimal)
+{
+ return garrow_decimal_less_than<arrow::Decimal128>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal128_less_than_or_equal:
+ * @decimal: A #GArrowDecimal128.
+ * @other_decimal: A #GArrowDecimal128 to be compared.
+ *
+ * Returns: %TRUE if the decimal is less than the other decimal
+ * or equal to the other decimal, %FALSE otherwise.
+ *
+ * Since: 0.12.0
+ */
+gboolean
+garrow_decimal128_less_than_or_equal(GArrowDecimal128 *decimal,
+ GArrowDecimal128 *other_decimal)
+{
+ return garrow_decimal_less_than_or_equal<arrow::Decimal128>(decimal,
other_decimal);
+}
+
+/**
+ * garrow_decimal128_greater_than:
+ * @decimal: A #GArrowDecimal128.
+ * @other_decimal: A #GArrowDecimal128 to be compared.
+ *
+ * Returns: %TRUE if the decimal is greater than the other decimal,
+ * %FALSE otherwise.
+ *
+ * Since: 0.12.0
+ */
+gboolean
+garrow_decimal128_greater_than(GArrowDecimal128 *decimal,
+ GArrowDecimal128 *other_decimal)
+{
+ return garrow_decimal_greater_than<arrow::Decimal128>(decimal,
other_decimal);
+}
+
+/**
+ * garrow_decimal128_greater_than_or_equal:
+ * @decimal: A #GArrowDecimal128.
+ * @other_decimal: A #GArrowDecimal128 to be compared.
+ *
+ * Returns: %TRUE if the decimal is greater than the other decimal
+ * or equal to the other decimal, %FALSE otherwise.
+ *
+ * Since: 0.12.0
+ */
+gboolean
+garrow_decimal128_greater_than_or_equal(GArrowDecimal128 *decimal,
+ GArrowDecimal128 *other_decimal)
+{
+ return garrow_decimal_greater_than_or_equal<arrow::Decimal128>(decimal,
other_decimal);
+}
+
+/**
+ * garrow_decimal128_to_string_scale:
+ * @decimal: A #GArrowDecimal128.
+ * @scale: The scale of the decimal.
+ *
+ * Returns: The string representation of the decimal.
+ *
+ * It should be freed with g_free() when no longer needed.
+ *
+ * Since: 0.10.0
+ */
+gchar *
+garrow_decimal128_to_string_scale(GArrowDecimal128 *decimal, gint32 scale)
+{
+ return garrow_decimal_to_string_scale<arrow::Decimal128>(decimal, scale);
+}
+
+/**
+ * garrow_decimal128_to_string:
+ * @decimal: A #GArrowDecimal128.
+ *
+ * Returns: The string representation of the decimal.
+ *
+ * It should be freed with g_free() when no longer needed.
+ *
+ * Since: 0.10.0
+ */
+gchar *
+garrow_decimal128_to_string(GArrowDecimal128 *decimal)
+{
+ return garrow_decimal_to_string<arrow::Decimal128>(decimal);
+}
+
+/**
+ * garrow_decimal128_abs:
+ * @decimal: A #GArrowDecimal128.
+ *
+ * Computes the absolute value of the @decimal destructively.
+ *
+ * Since: 0.10.0
+ */
+void
+garrow_decimal128_abs(GArrowDecimal128 *decimal)
+{
+ garrow_decimal_abs<arrow::Decimal128>(decimal);
+}
+
+/**
+ * garrow_decimal128_negate:
+ * @decimal: A #GArrowDecimal128.
+ *
+ * Negate the current value of the @decimal destructively.
+ *
+ * Since: 0.10.0
+ */
+void
+garrow_decimal128_negate(GArrowDecimal128 *decimal)
+{
+ garrow_decimal_negate<arrow::Decimal128>(decimal);
+}
+
+/**
+ * garrow_decimal128_to_integer:
+ * @decimal: A #GArrowDecimal128.
+ *
+ * Returns: The 64-bit integer representation of the decimal.
+ *
+ * Since: 0.10.0
+ */
+gint64
+garrow_decimal128_to_integer(GArrowDecimal128 *decimal)
+{
+ auto arrow_decimal = garrow_decimal128_get_raw(decimal);
+ return static_cast<int64_t>(*arrow_decimal);
Review comment:
`gint64` instead of `int64_t`?
##########
File path: ruby/red-arrow/lib/arrow/decimal256.rb
##########
@@ -0,0 +1,42 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+module Arrow
+ class Decimal256
+ alias_method :to_s_raw, :to_s
+
+ # @overload to_s
+ #
+ # @return [String]
+ # The string representation of the decimal.
+ #
+ # @overload to_s(scale)
+ #
+ # @param scale [Integer] The scale of the decimal.
+ # @return [String]
+ # The string representation of the decimal including the scale.
+ #
+ # @since 3.0.0
+ def to_s(scale=nil)
+ if scale
+ to_string_scale(scale)
+ else
+ to_s_raw
+ end
+ end
+ end
+end
Review comment:
Same for `Arrow::Decimal256#negate`.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]