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

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


The following commit(s) were added to refs/heads/main by this push:
     new ce3812d4aa GH-23970: [GLib] Add support for duration (#48564)
ce3812d4aa is described below

commit ce3812d4aab9f03a37518c05cbcf0255d74e738f
Author: Sutou Kouhei <[email protected]>
AuthorDate: Thu Dec 18 09:41:32 2025 +0900

    GH-23970: [GLib] Add support for duration (#48564)
    
    ### Rationale for this change
    
    It's a primitive type.
    
    ### What changes are included in this PR?
    
    * Add `GArrowDurationDataType`
    * Add `GArrowDurationArray`
    * Add `GArrowDurationArrayBuilder`
    * Add `GArrowDurationScalar`
    
    ### Are these changes tested?
    
    Yes.
    
    ### Are there any user-facing changes?
    
    Yes.
    * GitHub Issue: #23970
    
    Authored-by: Sutou Kouhei <[email protected]>
    Signed-off-by: Sutou Kouhei <[email protected]>
---
 c_glib/arrow-glib/array-builder.cpp    | 97 ++++++++++++++++++++++++++++++++++
 c_glib/arrow-glib/array-builder.h      | 31 +++++++++++
 c_glib/arrow-glib/basic-array.cpp      | 85 +++++++++++++++++++++++++++++
 c_glib/arrow-glib/basic-array.h        | 25 +++++++++
 c_glib/arrow-glib/basic-data-type.cpp  | 57 ++++++++++++++++++++
 c_glib/arrow-glib/basic-data-type.h    | 20 +++++++
 c_glib/arrow-glib/scalar.cpp           | 57 ++++++++++++++++++++
 c_glib/arrow-glib/scalar.h             | 16 ++++++
 c_glib/test/helper/buildable.rb        |  6 +++
 c_glib/test/test-duration-array.rb     | 50 ++++++++++++++++++
 c_glib/test/test-duration-data-type.rb | 84 +++++++++++++++++++++++++++++
 c_glib/test/test-duration-scalar.rb    | 48 +++++++++++++++++
 12 files changed, 576 insertions(+)

diff --git a/c_glib/arrow-glib/array-builder.cpp 
b/c_glib/arrow-glib/array-builder.cpp
index e8300692ff..e85ade800d 100644
--- a/c_glib/arrow-glib/array-builder.cpp
+++ b/c_glib/arrow-glib/array-builder.cpp
@@ -442,6 +442,9 @@ G_BEGIN_DECLS
  * #GArrowMonthDayNanoArrayBuilder is the class to create a new
  * #GArrowMonthDayNanoArray.
  *
+ * #GArrowDurationArrayBuilder is the class to create a new
+ * #GArrowDurationArray.
+ *
  * #GArrowStringDictionaryArrayBuilder is the class to create a new
  * #GArrowDictionaryArray with a dictionary array of #GArrowStringArray.
  *
@@ -4841,6 +4844,97 @@ 
garrow_month_day_nano_interval_array_builder_append_values(
     });
 }
 
+G_DEFINE_TYPE(GArrowDurationArrayBuilder,
+              garrow_duration_array_builder,
+              GARROW_TYPE_ARRAY_BUILDER)
+
+static void
+garrow_duration_array_builder_init(GArrowDurationArrayBuilder *builder)
+{
+}
+
+static void
+garrow_duration_array_builder_class_init(GArrowDurationArrayBuilderClass 
*klass)
+{
+}
+
+/**
+ * garrow_duration_array_builder_new:
+ * @data_type: A #GArrowDurationDataType.
+ *
+ * Returns: A newly created #GArrowDurationArrayBuilder.
+ *
+ * Since: 23.0.0
+ */
+GArrowDurationArrayBuilder *
+garrow_duration_array_builder_new(GArrowDurationDataType *data_type)
+{
+  auto arrow_data_type = garrow_data_type_get_raw(GARROW_DATA_TYPE(data_type));
+  auto builder =
+    garrow_array_builder_new(arrow_data_type, NULL, 
"[duration-array-builder][new]");
+  return GARROW_DURATION_ARRAY_BUILDER(builder);
+}
+
+/**
+ * garrow_duration_array_builder_append_value:
+ * @builder: A #GArrowDurationArrayBuilder.
+ * @value: The elapsed time in 64-bit signed integer.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 23.0.0
+ */
+gboolean
+garrow_duration_array_builder_append_value(GArrowDurationArrayBuilder *builder,
+                                           gint64 value,
+                                           GError **error)
+{
+  return garrow_array_builder_append_value<arrow::DurationBuilder>(
+    GARROW_ARRAY_BUILDER(builder),
+    value,
+    error,
+    "[duration-array-builder][append-value]");
+}
+
+/**
+ * garrow_duration_array_builder_append_values:
+ * @builder: A #GArrowDurationArrayBuilder.
+ * @values: (array length=values_length): The array of the elapsed time in
+ *   64-bit signed integer.
+ * @values_length: The length of `values`.
+ * @is_valids: (nullable) (array length=is_valids_length): The array of
+ *   boolean that shows whether the Nth value is valid or not. If the
+ *   Nth `is_valids` is %TRUE, the Nth `values` is valid value. Otherwise
+ *   the Nth value is null value.
+ * @is_valids_length: The length of `is_valids`.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Append multiple values at once. It's more efficient than multiple
+ * `append` and `append_null` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 23.0.0
+ */
+gboolean
+garrow_duration_array_builder_append_values(GArrowDurationArrayBuilder 
*builder,
+                                            const gint64 *values,
+                                            gint64 values_length,
+                                            const gboolean *is_valids,
+                                            gint64 is_valids_length,
+                                            GError **error)
+{
+  return garrow_array_builder_append_values<arrow::DurationBuilder>(
+    GARROW_ARRAY_BUILDER(builder),
+    reinterpret_cast<const int64_t *>(values),
+    values_length,
+    is_valids,
+    is_valids_length,
+    error,
+    "[duration-array-builder][append-values]");
+}
+
 G_DEFINE_TYPE(GArrowBinaryDictionaryArrayBuilder,
               garrow_binary_dictionary_array_builder,
               GARROW_TYPE_ARRAY_BUILDER)
@@ -6892,6 +6986,9 @@ 
garrow_array_builder_new_raw(std::shared_ptr<arrow::ArrayBuilder> *arrow_builder
     case arrow::Type::type::INTERVAL_MONTH_DAY_NANO:
       type = GARROW_TYPE_MONTH_DAY_NANO_INTERVAL_ARRAY_BUILDER;
       break;
+    case arrow::Type::type::DURATION:
+      type = GARROW_TYPE_DURATION_ARRAY_BUILDER;
+      break;
     case arrow::Type::type::LIST:
       type = GARROW_TYPE_LIST_ARRAY_BUILDER;
       break;
diff --git a/c_glib/arrow-glib/array-builder.h 
b/c_glib/arrow-glib/array-builder.h
index a4ccb8d224..037999244c 100644
--- a/c_glib/arrow-glib/array-builder.h
+++ b/c_glib/arrow-glib/array-builder.h
@@ -1442,6 +1442,37 @@ 
garrow_month_day_nano_interval_array_builder_append_values(
   gint64 is_valids_length,
   GError **error);
 
+#define GARROW_TYPE_DURATION_ARRAY_BUILDER 
(garrow_duration_array_builder_get_type())
+GARROW_AVAILABLE_IN_ALL
+G_DECLARE_DERIVABLE_TYPE(GArrowDurationArrayBuilder,
+                         garrow_duration_array_builder,
+                         GARROW,
+                         DURATION_ARRAY_BUILDER,
+                         GArrowArrayBuilder)
+struct _GArrowDurationArrayBuilderClass
+{
+  GArrowArrayBuilderClass parent_class;
+};
+
+GARROW_AVAILABLE_IN_23_0
+GArrowDurationArrayBuilder *
+garrow_duration_array_builder_new(GArrowDurationDataType *data_type);
+
+GARROW_AVAILABLE_IN_23_0
+gboolean
+garrow_duration_array_builder_append_value(GArrowDurationArrayBuilder *builder,
+                                           gint64 value,
+                                           GError **error);
+
+GARROW_AVAILABLE_IN_23_0
+gboolean
+garrow_duration_array_builder_append_values(GArrowDurationArrayBuilder 
*builder,
+                                            const gint64 *values,
+                                            gint64 values_length,
+                                            const gboolean *is_valids,
+                                            gint64 is_valids_length,
+                                            GError **error);
+
 #define GARROW_TYPE_BINARY_DICTIONARY_ARRAY_BUILDER                            
          \
   (garrow_binary_dictionary_array_builder_get_type())
 GARROW_AVAILABLE_IN_2_0
diff --git a/c_glib/arrow-glib/basic-array.cpp 
b/c_glib/arrow-glib/basic-array.cpp
index e42d2ed162..cf6e94738e 100644
--- a/c_glib/arrow-glib/basic-array.cpp
+++ b/c_glib/arrow-glib/basic-array.cpp
@@ -184,6 +184,11 @@ G_BEGIN_DECLS
  * have Arrow format data, you need to use #GArrowMonthDayNanoIntervalArray
  * to create a new array.
  *
+ * #GArrowDurationArray is a class for the elapsed time in 64-bit
+ * signed integer array. It can store zero or more duration data. If
+ * you don't have Arrow format data, you need to use
+ * #GArrowDurationArrayBuilder to create a new array.
+ *
  * #GArrowDecimal32Array is a class for 32-bit decimal array. It can
  * store zero or more 32-bit decimal data. If you don't have Arrow
  * format data, you need to use #GArrowDecimal32ArrayBuilder to
@@ -3452,6 +3457,83 @@ 
garrow_month_day_nano_interval_array_get_values(GArrowMonthDayNanoIntervalArray
   return g_list_reverse(values);
 }
 
+G_DEFINE_TYPE(GArrowDurationArray, garrow_duration_array, 
GARROW_TYPE_NUMERIC_ARRAY)
+
+static void
+garrow_duration_array_init(GArrowDurationArray *object)
+{
+}
+
+static void
+garrow_duration_array_class_init(GArrowDurationArrayClass *klass)
+{
+}
+
+/**
+ * garrow_duration_array_new:
+ * @data_type: The #GArrowDurationDataType.
+ * @length: The number of elements.
+ * @data: The binary data in Arrow format of the array.
+ * @null_bitmap: (nullable): The bitmap that shows null elements. The
+ *   N-th element is null when the N-th bit is 0, not null otherwise.
+ *   If the array has no null elements, the bitmap must be %NULL and
+ *   @n_nulls is 0.
+ * @n_nulls: The number of null elements. If -1 is specified, the
+ *   number of nulls are computed from @null_bitmap.
+ *
+ * Returns: A newly created #GArrowDurationArray.
+ *
+ * Since: 23.0.0
+ */
+GArrowDurationArray *
+garrow_duration_array_new(GArrowDurationDataType *data_type,
+                          gint64 length,
+                          GArrowBuffer *data,
+                          GArrowBuffer *null_bitmap,
+                          gint64 n_nulls)
+{
+  auto array =
+    
garrow_primitive_array_new<arrow::DurationType>(GARROW_DATA_TYPE(data_type),
+                                                    length,
+                                                    data,
+                                                    null_bitmap,
+                                                    n_nulls);
+  return GARROW_DURATION_ARRAY(array);
+}
+
+/**
+ * garrow_duration_array_get_value:
+ * @array: A #GArrowDurationArray.
+ * @i: The index of the target value.
+ *
+ * Returns: The @i-th value.
+ *
+ * Since: 23.0.0
+ */
+gint64
+garrow_duration_array_get_value(GArrowDurationArray *array, gint64 i)
+{
+  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
+  return static_cast<arrow::DurationArray *>(arrow_array.get())->Value(i);
+}
+
+/**
+ * garrow_duration_array_get_values:
+ * @array: A #GArrowDurationArray.
+ * @length: (out): The number of values.
+ *
+ * Returns: (array length=length): The raw values.
+ *
+ * Since: 23.0.0
+ */
+const gint64 *
+garrow_duration_array_get_values(GArrowDurationArray *array, gint64 *length)
+{
+  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
+  auto values = garrow_array_get_values_raw<arrow::DurationType>(arrow_array, 
length);
+  return reinterpret_cast<const gint64 *>(values);
+}
+
 G_DEFINE_TYPE(GArrowFixedSizeBinaryArray,
               garrow_fixed_size_binary_array,
               GARROW_TYPE_PRIMITIVE_ARRAY)
@@ -3999,6 +4081,9 @@ garrow_array_new_raw_valist(std::shared_ptr<arrow::Array> 
*arrow_array,
   case arrow::Type::type::INTERVAL_MONTH_DAY_NANO:
     type = GARROW_TYPE_MONTH_DAY_NANO_INTERVAL_ARRAY;
     break;
+  case arrow::Type::type::DURATION:
+    type = GARROW_TYPE_DURATION_ARRAY;
+    break;
   case arrow::Type::type::LIST:
     type = GARROW_TYPE_LIST_ARRAY;
     break;
diff --git a/c_glib/arrow-glib/basic-array.h b/c_glib/arrow-glib/basic-array.h
index 37f61a91cc..5a90e203e8 100644
--- a/c_glib/arrow-glib/basic-array.h
+++ b/c_glib/arrow-glib/basic-array.h
@@ -885,6 +885,31 @@ GARROW_AVAILABLE_IN_8_0
 GList *
 
garrow_month_day_nano_interval_array_get_values(GArrowMonthDayNanoIntervalArray 
*array);
 
+#define GARROW_TYPE_DURATION_ARRAY (garrow_duration_array_get_type())
+GARROW_AVAILABLE_IN_ALL
+G_DECLARE_DERIVABLE_TYPE(
+  GArrowDurationArray, garrow_duration_array, GARROW, DURATION_ARRAY, 
GArrowNumericArray)
+struct _GArrowDurationArrayClass
+{
+  GArrowNumericArrayClass parent_class;
+};
+
+GARROW_AVAILABLE_IN_23_0
+GArrowDurationArray *
+garrow_duration_array_new(GArrowDurationDataType *data_type,
+                          gint64 length,
+                          GArrowBuffer *data,
+                          GArrowBuffer *null_bitmap,
+                          gint64 n_nulls);
+
+GARROW_AVAILABLE_IN_23_0
+gint64
+garrow_duration_array_get_value(GArrowDurationArray *array, gint64 i);
+
+GARROW_AVAILABLE_IN_23_0
+const gint64 *
+garrow_duration_array_get_values(GArrowDurationArray *array, gint64 *length);
+
 #define GARROW_TYPE_FIXED_SIZE_BINARY_ARRAY 
(garrow_fixed_size_binary_array_get_type())
 GARROW_AVAILABLE_IN_3_0
 G_DECLARE_DERIVABLE_TYPE(GArrowFixedSizeBinaryArray,
diff --git a/c_glib/arrow-glib/basic-data-type.cpp 
b/c_glib/arrow-glib/basic-data-type.cpp
index 51fffb7369..9b77e87422 100644
--- a/c_glib/arrow-glib/basic-data-type.cpp
+++ b/c_glib/arrow-glib/basic-data-type.cpp
@@ -114,6 +114,10 @@ G_BEGIN_DECLS
  * #GArrowMonthDayNanoIntervalDataType is a class for the month day
  * nano intarval data type.
  *
+ * #GArrowDurationDataType is a class for the elapsed time in the
+ * 64-bit signed integer data type. It can use one of
+ * seconds/milliseconds/microseconds/nanoseconds as unit.
+ *
  * #GArrowDecimalDataType is a base class for the decimal data types.
  *
  * #GArrowDecimal32DataType is a class for the 32-bit decimal data type.
@@ -1482,6 +1486,56 @@ garrow_month_day_nano_interval_data_type_new(void)
   return GARROW_MONTH_DAY_NANO_INTERVAL_DATA_TYPE(data_type);
 }
 
+G_DEFINE_TYPE(GArrowDurationDataType,
+              garrow_duration_data_type,
+              GARROW_TYPE_TEMPORAL_DATA_TYPE)
+
+static void
+garrow_duration_data_type_init(GArrowDurationDataType *object)
+{
+}
+
+static void
+garrow_duration_data_type_class_init(GArrowDurationDataTypeClass *klass)
+{
+}
+
+/**
+ * garrow_duration_data_type_new:
+ * @unit: The unit of the duration data.
+ *
+ * Returns: A newly created the elapsed time in 64-bit signed integer
+ *   data type.
+ *
+ * Since: 23.0.0
+ */
+GArrowDurationDataType *
+garrow_duration_data_type_new(GArrowTimeUnit unit)
+{
+  auto arrow_unit = garrow_time_unit_to_raw(unit);
+  auto arrow_data_type = arrow::duration(arrow_unit);
+  auto data_type = GARROW_DURATION_DATA_TYPE(
+    g_object_new(GARROW_TYPE_DURATION_DATA_TYPE, "data-type", 
&arrow_data_type, nullptr));
+  return data_type;
+}
+
+/**
+ * garrow_duration_data_type_get_unit:
+ * @data_type: The #GArrowDurationDataType.
+ *
+ * Returns: The unit of the duration data type.
+ *
+ * Since: 23.0.0
+ */
+GArrowTimeUnit
+garrow_duration_data_type_get_unit(GArrowDurationDataType *data_type)
+{
+  const auto arrow_data_type = 
garrow_data_type_get_raw(GARROW_DATA_TYPE(data_type));
+  const auto arrow_duration_data_type =
+    std::static_pointer_cast<arrow::DurationType>(arrow_data_type);
+  return garrow_time_unit_from_raw(arrow_duration_data_type->unit());
+}
+
 G_DEFINE_ABSTRACT_TYPE(GArrowDecimalDataType,
                        garrow_decimal_data_type,
                        GARROW_TYPE_FIXED_SIZE_BINARY_DATA_TYPE)
@@ -2640,6 +2694,9 @@ garrow_data_type_new_raw(std::shared_ptr<arrow::DataType> 
*arrow_data_type)
   case arrow::Type::type::INTERVAL_MONTH_DAY_NANO:
     type = GARROW_TYPE_MONTH_DAY_NANO_INTERVAL_DATA_TYPE;
     break;
+  case arrow::Type::type::DURATION:
+    type = GARROW_TYPE_DURATION_DATA_TYPE;
+    break;
   case arrow::Type::type::EXTENSION:
     {
       auto g_extension_data_type =
diff --git a/c_glib/arrow-glib/basic-data-type.h 
b/c_glib/arrow-glib/basic-data-type.h
index d3998bd81b..960051d457 100644
--- a/c_glib/arrow-glib/basic-data-type.h
+++ b/c_glib/arrow-glib/basic-data-type.h
@@ -584,6 +584,26 @@ GARROW_AVAILABLE_IN_7_0
 GArrowMonthDayNanoIntervalDataType *
 garrow_month_day_nano_interval_data_type_new(void);
 
+#define GARROW_TYPE_DURATION_DATA_TYPE (garrow_duration_data_type_get_type())
+GARROW_AVAILABLE_IN_ALL
+G_DECLARE_DERIVABLE_TYPE(GArrowDurationDataType,
+                         garrow_duration_data_type,
+                         GARROW,
+                         DURATION_DATA_TYPE,
+                         GArrowTemporalDataType)
+struct _GArrowDurationDataTypeClass
+{
+  GArrowTemporalDataTypeClass parent_class;
+};
+
+GARROW_AVAILABLE_IN_23_0
+GArrowDurationDataType *
+garrow_duration_data_type_new(GArrowTimeUnit unit);
+
+GARROW_AVAILABLE_IN_23_0
+GArrowTimeUnit
+garrow_duration_data_type_get_unit(GArrowDurationDataType *data_type);
+
 #define GARROW_TYPE_DECIMAL_DATA_TYPE (garrow_decimal_data_type_get_type())
 GARROW_AVAILABLE_IN_ALL
 G_DECLARE_DERIVABLE_TYPE(GArrowDecimalDataType,
diff --git a/c_glib/arrow-glib/scalar.cpp b/c_glib/arrow-glib/scalar.cpp
index f2093e3e41..9c9e21310e 100644
--- a/c_glib/arrow-glib/scalar.cpp
+++ b/c_glib/arrow-glib/scalar.cpp
@@ -104,6 +104,9 @@ G_BEGIN_DECLS
  * #GArrowMonthDayNanoIntervalScalar is a class for the month day nano
  * intarval scalar.
  *
+ * #GArrowDurationScalar is a class for the elapsed time in a 64-bit
+ * signed integer scalar.
+ *
  * #GArrowDecimal32Scalar is a class for a 32-bit decimal scalar.
  *
  * #GArrowDecimal64Scalar is a class for a 64-bit decimal scalar.
@@ -1635,6 +1638,57 @@ 
garrow_month_day_nano_interval_scalar_get_value(GArrowMonthDayNanoIntervalScalar
   return priv->value;
 }
 
+G_DEFINE_TYPE(GArrowDurationScalar, garrow_duration_scalar, GARROW_TYPE_SCALAR)
+
+static void
+garrow_duration_scalar_init(GArrowDurationScalar *object)
+{
+}
+
+static void
+garrow_duration_scalar_class_init(GArrowDurationScalarClass *klass)
+{
+}
+
+/**
+ * garrow_duration_scalar_new:
+ * @data_type: A #GArrowDurationDataType for this scalar.
+ * @value: The value of this scalar.
+ *
+ * Returns: A newly created #GArrowDurationScalar.
+ *
+ * Since: 23.0.0
+ */
+GArrowDurationScalar *
+garrow_duration_scalar_new(GArrowDurationDataType *data_type, gint64 value)
+{
+  auto arrow_data_type = garrow_data_type_get_raw(GARROW_DATA_TYPE(data_type));
+  auto arrow_scalar = std::static_pointer_cast<arrow::Scalar>(
+    std::make_shared<arrow::DurationScalar>(value, arrow_data_type));
+  return GARROW_DURATION_SCALAR(garrow_scalar_new_raw(&arrow_scalar,
+                                                      "scalar",
+                                                      &arrow_scalar,
+                                                      "data-type",
+                                                      data_type,
+                                                      nullptr));
+}
+
+/**
+ * garrow_duration_scalar_get_value:
+ * @scalar: A #GArrowDurationScalar.
+ *
+ * Returns: The value of this scalar.
+ *
+ * Since: 23.0.0
+ */
+gint64
+garrow_duration_scalar_get_value(GArrowDurationScalar *scalar)
+{
+  const auto arrow_scalar = std::static_pointer_cast<arrow::DurationScalar>(
+    garrow_scalar_get_raw(GARROW_SCALAR(scalar)));
+  return arrow_scalar->value;
+}
+
 typedef struct GArrowDecimal32ScalarPrivate_
 {
   GArrowDecimal32 *value;
@@ -2754,6 +2808,9 @@ 
garrow_scalar_new_raw_valist(std::shared_ptr<arrow::Scalar> *arrow_scalar,
   case arrow::Type::type::INTERVAL_MONTH_DAY_NANO:
     type = GARROW_TYPE_MONTH_DAY_NANO_INTERVAL_SCALAR;
     break;
+  case arrow::Type::type::DURATION:
+    type = GARROW_TYPE_DURATION_SCALAR;
+    break;
   case arrow::Type::type::DECIMAL32:
     type = GARROW_TYPE_DECIMAL32_SCALAR;
     break;
diff --git a/c_glib/arrow-glib/scalar.h b/c_glib/arrow-glib/scalar.h
index 4f2c44199f..675d7b7ec1 100644
--- a/c_glib/arrow-glib/scalar.h
+++ b/c_glib/arrow-glib/scalar.h
@@ -501,6 +501,22 @@ GARROW_AVAILABLE_IN_8_0
 GArrowMonthDayNano *
 
garrow_month_day_nano_interval_scalar_get_value(GArrowMonthDayNanoIntervalScalar
 *scalar);
 
+#define GARROW_TYPE_DURATION_SCALAR (garrow_duration_scalar_get_type())
+GARROW_AVAILABLE_IN_23_0
+G_DECLARE_DERIVABLE_TYPE(
+  GArrowDurationScalar, garrow_duration_scalar, GARROW, DURATION_SCALAR, 
GArrowScalar)
+struct _GArrowDurationScalarClass
+{
+  GArrowScalarClass parent_class;
+};
+
+GARROW_AVAILABLE_IN_23_0
+GArrowDurationScalar *
+garrow_duration_scalar_new(GArrowDurationDataType *data_type, gint64 value);
+GARROW_AVAILABLE_IN_23_0
+gint64
+garrow_duration_scalar_get_value(GArrowDurationScalar *scalar);
+
 #define GARROW_TYPE_DECIMAL32_SCALAR (garrow_decimal32_scalar_get_type())
 GARROW_AVAILABLE_IN_19_0
 G_DECLARE_DERIVABLE_TYPE(
diff --git a/c_glib/test/helper/buildable.rb b/c_glib/test/helper/buildable.rb
index e7c4f98d53..77ab3af0a6 100644
--- a/c_glib/test/helper/buildable.rb
+++ b/c_glib/test/helper/buildable.rb
@@ -118,6 +118,12 @@ module Helper
                   values)
     end
 
+    def build_duration_array(unit, values)
+      data_type = Arrow::DurationDataType.new(unit)
+      build_array(Arrow::DurationArrayBuilder.new(data_type),
+                  values)
+    end
+
     def build_binary_array(values)
       build_array(Arrow::BinaryArrayBuilder.new, values)
     end
diff --git a/c_glib/test/test-duration-array.rb 
b/c_glib/test/test-duration-array.rb
new file mode 100644
index 0000000000..9592965c02
--- /dev/null
+++ b/c_glib/test/test-duration-array.rb
@@ -0,0 +1,50 @@
+# 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.
+
+class TestDurationArray < Test::Unit::TestCase
+  include Helper::Buildable
+
+  def test_new
+    raw_data = [0, 1000]
+    data_type = Arrow::DurationDataType.new(:second)
+    assert_equal(build_duration_array(:second, [*raw_data, nil]),
+                 Arrow::DurationArray.new(data_type,
+                                          3,
+                                          
Arrow::Buffer.new(raw_data.pack("q*")),
+                                          
Arrow::Buffer.new([0b011].pack("C*")),
+                                          -1))
+  end
+
+  def test_buffer
+    raw_data = [0, 1000]
+    array = build_duration_array(:milli, raw_data)
+    assert_equal(raw_data.pack("q*"),
+                 array.buffer.data.to_s)
+  end
+
+  def test_value
+    duration = 1000
+    array = build_duration_array(:milli, [duration])
+    assert_equal(duration, array.get_value(0))
+  end
+
+  def test_values
+    raw_data = [0, 1000]
+    array = build_duration_array(:milli, raw_data)
+    assert_equal(raw_data, array.values)
+  end
+end
diff --git a/c_glib/test/test-duration-data-type.rb 
b/c_glib/test/test-duration-data-type.rb
new file mode 100644
index 0000000000..7f92df6e1a
--- /dev/null
+++ b/c_glib/test/test-duration-data-type.rb
@@ -0,0 +1,84 @@
+# 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.
+
+class TestDurationDataType < Test::Unit::TestCase
+  def test_type
+    data_type = Arrow::DurationDataType.new(:micro)
+    assert_equal(Arrow::Type::DURATION, data_type.id)
+  end
+
+  def test_name
+    data_type = Arrow::DurationDataType.new(:micro)
+    assert_equal("duration", data_type.name)
+  end
+
+  sub_test_case("second") do
+    def setup
+      @data_type = Arrow::DurationDataType.new(:second)
+    end
+
+    def test_to_s
+      assert_equal("duration[s]", @data_type.to_s)
+    end
+
+    def test_unit
+      assert_equal(Arrow::TimeUnit::SECOND, @data_type.unit)
+    end
+  end
+
+  sub_test_case("millisecond") do
+    def setup
+      @data_type = Arrow::DurationDataType.new(:milli)
+    end
+
+    def test_to_s
+      assert_equal("duration[ms]", @data_type.to_s)
+    end
+
+    def test_unit
+      assert_equal(Arrow::TimeUnit::MILLI, @data_type.unit)
+    end
+  end
+
+  sub_test_case("micro") do
+    def setup
+      @data_type = Arrow::DurationDataType.new(:micro)
+    end
+
+    def test_to_s
+      assert_equal("duration[us]", @data_type.to_s)
+    end
+
+    def test_unit
+      assert_equal(Arrow::TimeUnit::MICRO, @data_type.unit)
+    end
+  end
+
+  sub_test_case("nano") do
+    def setup
+      @data_type = Arrow::DurationDataType.new(:nano)
+    end
+
+    def test_to_s
+      assert_equal("duration[ns]", @data_type.to_s)
+    end
+
+    def test_unit
+      assert_equal(Arrow::TimeUnit::NANO, @data_type.unit)
+    end
+  end
+end
diff --git a/c_glib/test/test-duration-scalar.rb 
b/c_glib/test/test-duration-scalar.rb
new file mode 100644
index 0000000000..7c77e5c777
--- /dev/null
+++ b/c_glib/test/test-duration-scalar.rb
@@ -0,0 +1,48 @@
+# 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.
+
+class TestDurationScalar < Test::Unit::TestCase
+  def setup
+    @data_type = Arrow::DurationDataType.new(:milli)
+    @value = 1000
+    @scalar = Arrow::DurationScalar.new(@data_type, @value)
+  end
+
+  def test_data_type
+    assert_equal(@data_type,
+                 @scalar.data_type)
+  end
+
+  def test_valid?
+    assert do
+      @scalar.valid?
+    end
+  end
+
+  def test_equal
+    assert_equal(Arrow::DurationScalar.new(@data_type, @value),
+                 @scalar)
+  end
+
+  def test_to_s
+    assert_equal("1000", @scalar.to_s)
+  end
+
+  def test_value
+    assert_equal(@value, @scalar.value)
+  end
+end

Reply via email to