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

kou 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 68ed635  ARROW-9051: [GLib] Refer Array related objects from Array
68ed635 is described below

commit 68ed63514f02fdba4b04dd6542e29c0427775e79
Author: Sutou Kouhei <[email protected]>
AuthorDate: Tue Jun 9 08:38:21 2020 +0900

    ARROW-9051: [GLib] Refer Array related objects from Array
    
    It's for preventing from freeing needed data.
    
    Closes #7363 from kou/glib-array-refer-related-objects
    
    Authored-by: Sutou Kouhei <[email protected]>
    Signed-off-by: Sutou Kouhei <[email protected]>
---
 c_glib/arrow-glib/basic-array.cpp     |  599 +++++++++++++-----
 c_glib/arrow-glib/basic-array.h       |   31 +-
 c_glib/arrow-glib/basic-array.hpp     |   14 +-
 c_glib/arrow-glib/buffer.cpp          |   13 +-
 c_glib/arrow-glib/composite-array.cpp | 1099 +++++++++++++++++++++++++++------
 c_glib/arrow-glib/composite-array.h   |    6 +-
 6 files changed, 1395 insertions(+), 367 deletions(-)

diff --git a/c_glib/arrow-glib/basic-array.cpp 
b/c_glib/arrow-glib/basic-array.cpp
index 16f8416..dc45db7 100644
--- a/c_glib/arrow-glib/basic-array.cpp
+++ b/c_glib/arrow-glib/basic-array.cpp
@@ -30,58 +30,6 @@
 
 #include <sstream>
 
-template <typename T>
-const typename T::c_type *
-garrow_array_get_values_raw(std::shared_ptr<arrow::Array> arrow_array,
-                            gint64 *length)
-{
-  auto arrow_specific_array =
-    std::static_pointer_cast<typename 
arrow::TypeTraits<T>::ArrayType>(arrow_array);
-  *length = arrow_specific_array->length();
-  return arrow_specific_array->raw_values();
-};
-
-template <typename T>
-GArrowArray *
-garrow_primitive_array_new(gint64 length,
-                           GArrowBuffer *data,
-                           GArrowBuffer *null_bitmap,
-                           gint64 n_nulls)
-{
-  const auto arrow_data = garrow_buffer_get_raw(data);
-  const auto arrow_bitmap = garrow_buffer_get_raw(null_bitmap);
-  auto arrow_specific_array =
-    std::make_shared<typename arrow::TypeTraits<T>::ArrayType>(length,
-                                                               arrow_data,
-                                                               arrow_bitmap,
-                                                               n_nulls);
-  auto arrow_array =
-    std::static_pointer_cast<arrow::Array>(arrow_specific_array);
-  return garrow_array_new_raw(&arrow_array);
-};
-
-template <typename T>
-GArrowArray *
-garrow_primitive_array_new(GArrowDataType *data_type,
-                           gint64 length,
-                           GArrowBuffer *data,
-                           GArrowBuffer *null_bitmap,
-                           gint64 n_nulls)
-{
-  auto arrow_data_type = garrow_data_type_get_raw(data_type);
-  const auto arrow_data = garrow_buffer_get_raw(data);
-  const auto arrow_bitmap = garrow_buffer_get_raw(null_bitmap);
-  auto arrow_specific_array =
-    std::make_shared<typename arrow::TypeTraits<T>::ArrayType>(arrow_data_type,
-                                                               length,
-                                                               arrow_data,
-                                                               arrow_bitmap,
-                                                               n_nulls);
-  auto arrow_array =
-    std::static_pointer_cast<arrow::Array>(arrow_specific_array);
-  return garrow_array_new_raw(&arrow_array);
-};
-
 G_BEGIN_DECLS
 
 /**
@@ -211,11 +159,24 @@ G_BEGIN_DECLS
 
 typedef struct GArrowArrayPrivate_ {
   std::shared_ptr<arrow::Array> array;
+  GArrowDataType *value_data_type;
+  GArrowBuffer *null_bitmap;
+  // Data for primitive array, value offsets for list array, type
+  // codes for union array and so on.
+  GArrowBuffer *buffer1;
+  // Data for binary array, value offsets for dense union array and so
+  // on.
+  GArrowBuffer *buffer2;
+  GArrowArray *parent;
 } GArrowArrayPrivate;
 
 enum {
-  PROP_0,
-  PROP_ARRAY
+  PROP_ARRAY = 1,
+  PROP_VALUE_DATA_TYPE,
+  PROP_NULL_BITMAP,
+  PROP_BUFFER1,
+  PROP_BUFFER2,
+  PROP_PARENT,
 };
 
 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(GArrowArray,
@@ -224,8 +185,54 @@ G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(GArrowArray,
 
 #define GARROW_ARRAY_GET_PRIVATE(obj)         \
   static_cast<GArrowArrayPrivate *>(          \
-     garrow_array_get_instance_private(       \
-       GARROW_ARRAY(obj)))
+    garrow_array_get_instance_private(        \
+      GARROW_ARRAY(obj)))
+
+G_END_DECLS
+template <typename T>
+const typename T::c_type *
+garrow_array_get_values_raw(std::shared_ptr<arrow::Array> arrow_array,
+                            gint64 *length)
+{
+  auto arrow_specific_array =
+    std::static_pointer_cast<typename 
arrow::TypeTraits<T>::ArrayType>(arrow_array);
+  *length = arrow_specific_array->length();
+  return arrow_specific_array->raw_values();
+};
+G_BEGIN_DECLS
+
+static void
+garrow_array_dispose(GObject *object)
+{
+  auto priv = GARROW_ARRAY_GET_PRIVATE(object);
+
+  if (priv->value_data_type) {
+    g_object_unref(priv->value_data_type);
+    priv->value_data_type = NULL;
+  }
+
+  if (priv->null_bitmap) {
+    g_object_unref(priv->null_bitmap);
+    priv->null_bitmap = NULL;
+  }
+
+  if (priv->buffer1) {
+    g_object_unref(priv->buffer1);
+    priv->buffer1 = NULL;
+  }
+
+  if (priv->buffer2) {
+    g_object_unref(priv->buffer2);
+    priv->buffer2 = NULL;
+  }
+
+  if (priv->parent) {
+    g_object_unref(priv->parent);
+    priv->parent = NULL;
+  }
+
+  G_OBJECT_CLASS(garrow_array_parent_class)->dispose(object);
+}
 
 static void
 garrow_array_finalize(GObject *object)
@@ -250,6 +257,21 @@ garrow_array_set_property(GObject *object,
     priv->array =
       *static_cast<std::shared_ptr<arrow::Array> 
*>(g_value_get_pointer(value));
     break;
+  case PROP_VALUE_DATA_TYPE:
+    priv->value_data_type = GARROW_DATA_TYPE(g_value_dup_object(value));
+    break;
+  case PROP_NULL_BITMAP:
+    priv->null_bitmap = GARROW_BUFFER(g_value_dup_object(value));
+    break;
+  case PROP_BUFFER1:
+    priv->buffer1 = GARROW_BUFFER(g_value_dup_object(value));
+    break;
+  case PROP_BUFFER2:
+    priv->buffer2 = GARROW_BUFFER(g_value_dup_object(value));
+    break;
+  case PROP_PARENT:
+    priv->parent = GARROW_ARRAY(g_value_dup_object(value));
+    break;
   default:
     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
     break;
@@ -262,7 +284,24 @@ garrow_array_get_property(GObject *object,
                           GValue *value,
                           GParamSpec *pspec)
 {
+  auto priv = GARROW_ARRAY_GET_PRIVATE(object);
+
   switch (prop_id) {
+  case PROP_VALUE_DATA_TYPE:
+    g_value_set_object(value, priv->value_data_type);
+    break;
+  case PROP_NULL_BITMAP:
+    g_value_set_object(value, priv->null_bitmap);
+    break;
+  case PROP_BUFFER1:
+    g_value_set_object(value, priv->buffer1);
+    break;
+  case PROP_BUFFER2:
+    g_value_set_object(value, priv->buffer2);
+    break;
+  case PROP_PARENT:
+    g_value_set_object(value, priv->parent);
+    break;
   default:
     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
     break;
@@ -279,20 +318,61 @@ garrow_array_init(GArrowArray *object)
 static void
 garrow_array_class_init(GArrowArrayClass *klass)
 {
-  GParamSpec *spec;
-
   auto gobject_class = G_OBJECT_CLASS(klass);
 
+  gobject_class->dispose      = garrow_array_dispose;
   gobject_class->finalize     = garrow_array_finalize;
   gobject_class->set_property = garrow_array_set_property;
   gobject_class->get_property = garrow_array_get_property;
 
+  GParamSpec *spec;
   spec = g_param_spec_pointer("array",
                               "Array",
                               "The raw std::shared<arrow::Array> *",
-                              static_cast<GParamFlags>(G_PARAM_WRITABLE |
+                              static_cast<GParamFlags>(G_PARAM_READWRITE |
                                                        
G_PARAM_CONSTRUCT_ONLY));
   g_object_class_install_property(gobject_class, PROP_ARRAY, spec);
+
+  spec = g_param_spec_object("value-data-type",
+                             "Value data type",
+                             "The data type of each value",
+                             GARROW_TYPE_DATA_TYPE,
+                             static_cast<GParamFlags>(G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_VALUE_DATA_TYPE, spec);
+
+  spec = g_param_spec_object("null-bitmap",
+                             "NULL bitmap",
+                             "The NULL bitmap",
+                             GARROW_TYPE_BUFFER,
+                             static_cast<GParamFlags>(G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_NULL_BITMAP, spec);
+
+  spec = g_param_spec_object("buffer1",
+                             "Buffer1",
+                             "The first buffer",
+                             GARROW_TYPE_BUFFER,
+                             static_cast<GParamFlags>(G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_BUFFER1, spec);
+
+  spec = g_param_spec_object("buffer2",
+                             "Buffer2",
+                             "The second buffer",
+                             GARROW_TYPE_BUFFER,
+                             static_cast<GParamFlags>(G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_BUFFER2, spec);
+
+  spec = g_param_spec_object("parent",
+                             "Parent",
+                             "The parent array",
+                             GARROW_TYPE_ARRAY,
+                             static_cast<GParamFlags>(G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_PARENT, spec);
+
 }
 
 /**
@@ -445,6 +525,12 @@ garrow_array_get_n_nulls(GArrowArray *array)
 GArrowBuffer *
 garrow_array_get_null_bitmap(GArrowArray *array)
 {
+  auto priv = GARROW_ARRAY_GET_PRIVATE(array);
+  if (priv->null_bitmap) {
+    g_object_ref(priv->null_bitmap);
+    return priv->null_bitmap;
+  }
+
   auto arrow_array = garrow_array_get_raw(array);
   auto arrow_null_bitmap = arrow_array->null_bitmap();
   return garrow_buffer_new_raw(&arrow_null_bitmap);
@@ -462,6 +548,12 @@ garrow_array_get_null_bitmap(GArrowArray *array)
 GArrowDataType *
 garrow_array_get_value_data_type(GArrowArray *array)
 {
+  auto priv = GARROW_ARRAY_GET_PRIVATE(array);
+  if (priv->value_data_type) {
+    g_object_ref(priv->value_data_type);
+    return priv->value_data_type;
+  }
+
   auto arrow_array = garrow_array_get_raw(array);
   auto arrow_data_type = arrow_array->type();
   return garrow_data_type_new_raw(&arrow_data_type);
@@ -499,7 +591,10 @@ garrow_array_slice(GArrowArray *array,
 {
   const auto arrow_array = garrow_array_get_raw(array);
   auto arrow_sub_array = arrow_array->Slice(offset, length);
-  return garrow_array_new_raw(&arrow_sub_array);
+  return garrow_array_new_raw(&arrow_sub_array,
+                              "array", &arrow_sub_array,
+                              "parent", array,
+                              NULL);
 }
 
 /**
@@ -613,6 +708,57 @@ G_DEFINE_TYPE(GArrowPrimitiveArray,
               garrow_primitive_array,
               GARROW_TYPE_ARRAY)
 
+G_END_DECLS
+template <typename T>
+GArrowArray *
+garrow_primitive_array_new(gint64 length,
+                           GArrowBuffer *data,
+                           GArrowBuffer *null_bitmap,
+                           gint64 n_nulls)
+{
+  const auto arrow_data = garrow_buffer_get_raw(data);
+  const auto arrow_bitmap = garrow_buffer_get_raw(null_bitmap);
+  auto arrow_specific_array =
+    std::make_shared<typename arrow::TypeTraits<T>::ArrayType>(length,
+                                                               arrow_data,
+                                                               arrow_bitmap,
+                                                               n_nulls);
+  auto arrow_array =
+    std::static_pointer_cast<arrow::Array>(arrow_specific_array);
+  return garrow_array_new_raw(&arrow_array,
+                              "array", &arrow_array,
+                              "null-bitmap", null_bitmap,
+                              "buffer1", data,
+                              NULL);
+};
+
+template <typename T>
+GArrowArray *
+garrow_primitive_array_new(GArrowDataType *data_type,
+                           gint64 length,
+                           GArrowBuffer *data,
+                           GArrowBuffer *null_bitmap,
+                           gint64 n_nulls)
+{
+  auto arrow_data_type = garrow_data_type_get_raw(data_type);
+  const auto arrow_data = garrow_buffer_get_raw(data);
+  const auto arrow_bitmap = garrow_buffer_get_raw(null_bitmap);
+  auto arrow_specific_array =
+    std::make_shared<typename arrow::TypeTraits<T>::ArrayType>(arrow_data_type,
+                                                               length,
+                                                               arrow_data,
+                                                               arrow_bitmap,
+                                                               n_nulls);
+  auto arrow_array =
+    std::static_pointer_cast<arrow::Array>(arrow_specific_array);
+  return garrow_array_new_raw(&arrow_array,
+                              "array", &arrow_array,
+                              "null-bitmap", null_bitmap,
+                              "buffer1", data,
+                              NULL);
+};
+G_BEGIN_DECLS
+
 static void
 garrow_primitive_array_init(GArrowPrimitiveArray *object)
 {
@@ -628,13 +774,35 @@ 
garrow_primitive_array_class_init(GArrowPrimitiveArrayClass *klass)
  * @array: A #GArrowPrimitiveArray.
  *
  * Returns: (transfer full): The data of the array as #GArrowBuffer.
+ *
+ * Deprecated: 1.0.0: Use garrow_primitive_array_get_data_buffer() instead.
  */
 GArrowBuffer *
 garrow_primitive_array_get_buffer(GArrowPrimitiveArray *array)
 {
+  return garrow_primitive_array_get_data_buffer(array);
+}
+
+/**
+ * garrow_primitive_array_get_data_buffer:
+ * @array: A #GArrowPrimitiveArray.
+ *
+ * Returns: (transfer full): The data of the array as #GArrowBuffer.
+ *
+ * Since: 1.0.0
+ */
+GArrowBuffer *
+garrow_primitive_array_get_data_buffer(GArrowPrimitiveArray *array)
+{
+  auto priv = GARROW_ARRAY_GET_PRIVATE(array);
+  if (priv->buffer1) {
+    g_object_ref(priv->buffer1);
+    return priv->buffer1;
+  }
+
   auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
   auto arrow_primitive_array =
-    static_cast<arrow::PrimitiveArray *>(arrow_array.get());
+    std::static_pointer_cast<arrow::PrimitiveArray>(arrow_array);
   auto arrow_data = arrow_primitive_array->values();
   return garrow_buffer_new_raw(&arrow_data);
 }
@@ -1471,6 +1639,81 @@ garrow_double_array_get_values(GArrowDoubleArray *array,
 }
 
 
+G_END_DECLS
+template <typename BINARY_ARRAY_CLASS>
+GArrowArray *
+garrow_base_binary_array_new(gint64 length,
+                             GArrowBuffer *value_offsets,
+                             GArrowBuffer *value_data,
+                             GArrowBuffer *null_bitmap,
+                             gint64 n_nulls)
+{
+  const auto arrow_value_offsets = garrow_buffer_get_raw(value_offsets);
+  const auto arrow_value_data = garrow_buffer_get_raw(value_data);
+  const auto arrow_null_bitmap = garrow_buffer_get_raw(null_bitmap);
+  auto arrow_binary_array =
+    std::make_shared<BINARY_ARRAY_CLASS>(length,
+                                         arrow_value_offsets,
+                                         arrow_value_data,
+                                         arrow_null_bitmap,
+                                         n_nulls);
+  auto arrow_array =
+    std::static_pointer_cast<arrow::Array>(arrow_binary_array);
+  return garrow_array_new_raw(&arrow_array,
+                              "array", &arrow_array,
+                              "null-bitmap", null_bitmap,
+                              "buffer1", value_offsets,
+                              "buffer2", value_data,
+                              NULL);
+};
+
+template <typename BINARY_ARRAY_CLASS>
+GBytes *
+garrow_base_binary_array_get_value(GArrowArray *array,
+                                   gint64 i)
+{
+  auto arrow_array = garrow_array_get_raw(array);
+  auto arrow_binary_array =
+    std::static_pointer_cast<BINARY_ARRAY_CLASS>(arrow_array);
+  auto view = arrow_binary_array->GetView(i);
+  return g_bytes_new_static(view.data(), view.length());
+};
+
+template <typename BINARY_ARRAY_CLASS>
+GArrowBuffer *
+garrow_base_binary_array_get_data_buffer(GArrowArray *array)
+{
+  auto priv = GARROW_ARRAY_GET_PRIVATE(array);
+  if (priv->buffer2) {
+    g_object_ref(priv->buffer2);
+    return priv->buffer2;
+  }
+
+  auto arrow_array = garrow_array_get_raw(array);
+  auto arrow_binary_array =
+    std::static_pointer_cast<BINARY_ARRAY_CLASS>(arrow_array);
+  auto arrow_data = arrow_binary_array->value_data();
+  return garrow_buffer_new_raw(&arrow_data);
+};
+
+template <typename BINARY_ARRAY_CLASS>
+GArrowBuffer *
+garrow_base_binary_array_get_offsets_buffer(GArrowArray *array)
+{
+  auto priv = GARROW_ARRAY_GET_PRIVATE(array);
+  if (priv->buffer1) {
+    g_object_ref(priv->buffer1);
+    return priv->buffer1;
+  }
+
+  auto arrow_array = garrow_array_get_raw(array);
+  auto arrow_binary_array =
+    std::static_pointer_cast<BINARY_ARRAY_CLASS>(arrow_array);
+  auto arrow_offsets = arrow_binary_array->value_offsets();
+  return garrow_buffer_new_raw(&arrow_offsets);
+};
+G_BEGIN_DECLS
+
 G_DEFINE_TYPE(GArrowBinaryArray,
               garrow_binary_array,
               GARROW_TYPE_ARRAY)
@@ -1489,7 +1732,7 @@ garrow_binary_array_class_init(GArrowBinaryArrayClass 
*klass)
  * garrow_binary_array_new:
  * @length: The number of elements.
  * @value_offsets: The value offsets of @data in Arrow format.
- * @data: The binary data in Arrow format of the array.
+ * @value_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
@@ -1504,22 +1747,17 @@ garrow_binary_array_class_init(GArrowBinaryArrayClass 
*klass)
 GArrowBinaryArray *
 garrow_binary_array_new(gint64 length,
                         GArrowBuffer *value_offsets,
-                        GArrowBuffer *data,
+                        GArrowBuffer *value_data,
                         GArrowBuffer *null_bitmap,
                         gint64 n_nulls)
 {
-  const auto arrow_value_offsets = garrow_buffer_get_raw(value_offsets);
-  const auto arrow_data = garrow_buffer_get_raw(data);
-  const auto arrow_bitmap = garrow_buffer_get_raw(null_bitmap);
-  auto arrow_binary_array =
-    std::make_shared<arrow::BinaryArray>(length,
-                                         arrow_value_offsets,
-                                         arrow_data,
-                                         arrow_bitmap,
-                                         n_nulls);
-  auto arrow_array =
-    std::static_pointer_cast<arrow::Array>(arrow_binary_array);
-  return GARROW_BINARY_ARRAY(garrow_array_new_raw(&arrow_array));
+  auto binary_array =
+    garrow_base_binary_array_new<arrow::BinaryArray>(length,
+                                                     value_offsets,
+                                                     value_data,
+                                                     null_bitmap,
+                                                     n_nulls);
+  return GARROW_BINARY_ARRAY(binary_array);
 }
 
 /**
@@ -1533,13 +1771,8 @@ GBytes *
 garrow_binary_array_get_value(GArrowBinaryArray *array,
                               gint64 i)
 {
-  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
-  auto arrow_binary_array =
-    static_cast<arrow::BinaryArray *>(arrow_array.get());
-
-  int32_t length;
-  auto value = arrow_binary_array->GetValue(i, &length);
-  return g_bytes_new_static(value, length);
+  return garrow_base_binary_array_get_value<arrow::BinaryArray>(
+    GARROW_ARRAY(array), i);
 }
 
 /**
@@ -1547,15 +1780,28 @@ garrow_binary_array_get_value(GArrowBinaryArray *array,
  * @array: A #GArrowBinaryArray.
  *
  * Returns: (transfer full): The data of the array as #GArrowBuffer.
+ *
+ * Deprecated: 1.0.0: Use garrow_binary_array_get_data_buffer() instead.
  */
 GArrowBuffer *
 garrow_binary_array_get_buffer(GArrowBinaryArray *array)
 {
-  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
-  auto arrow_binary_array =
-    static_cast<arrow::BinaryArray *>(arrow_array.get());
-  auto arrow_data = arrow_binary_array->value_data();
-  return garrow_buffer_new_raw(&arrow_data);
+  return garrow_binary_array_get_data_buffer(array);
+}
+
+/**
+ * garrow_binary_array_get_data_buffer:
+ * @array: A #GArrowBinaryArray.
+ *
+ * Returns: (transfer full): The data of the array as #GArrowBuffer.
+ *
+ * Since: 1.0.0
+ */
+GArrowBuffer *
+garrow_binary_array_get_data_buffer(GArrowBinaryArray *array)
+{
+  return garrow_base_binary_array_get_data_buffer<arrow::BinaryArray>(
+    GARROW_ARRAY(array));
 }
 
 /**
@@ -1567,11 +1813,8 @@ garrow_binary_array_get_buffer(GArrowBinaryArray *array)
 GArrowBuffer *
 garrow_binary_array_get_offsets_buffer(GArrowBinaryArray *array)
 {
-  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
-  auto arrow_binary_array =
-    static_cast<arrow::BinaryArray *>(arrow_array.get());
-  auto arrow_offsets = arrow_binary_array->value_offsets();
-  return garrow_buffer_new_raw(&arrow_offsets);
+  return garrow_base_binary_array_get_offsets_buffer<arrow::BinaryArray>(
+    GARROW_ARRAY(array));
 }
 
 
@@ -1593,7 +1836,7 @@ 
garrow_large_binary_array_class_init(GArrowLargeBinaryArrayClass *klass)
  * garrow_large_binary_array_new:
  * @length: The number of elements.
  * @value_offsets: The value offsets of @data in Arrow format.
- * @data: The binary data in Arrow format of the array.
+ * @value_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
@@ -1608,22 +1851,17 @@ 
garrow_large_binary_array_class_init(GArrowLargeBinaryArrayClass *klass)
 GArrowLargeBinaryArray *
 garrow_large_binary_array_new(gint64 length,
                               GArrowBuffer *value_offsets,
-                              GArrowBuffer *data,
+                              GArrowBuffer *value_data,
                               GArrowBuffer *null_bitmap,
                               gint64 n_nulls)
 {
-  const auto arrow_value_offsets = garrow_buffer_get_raw(value_offsets);
-  const auto arrow_data = garrow_buffer_get_raw(data);
-  const auto arrow_bitmap = garrow_buffer_get_raw(null_bitmap);
-  auto arrow_large_binary_array =
-    std::make_shared<arrow::LargeBinaryArray>(length,
-                                              arrow_value_offsets,
-                                              arrow_data,
-                                              arrow_bitmap,
-                                              n_nulls);
-  auto arrow_array =
-    std::static_pointer_cast<arrow::Array>(arrow_large_binary_array);
-  return GARROW_LARGE_BINARY_ARRAY(garrow_array_new_raw(&arrow_array));
+  auto large_binary_array =
+    garrow_base_binary_array_new<arrow::LargeBinaryArray>(length,
+                                                          value_offsets,
+                                                          value_data,
+                                                          null_bitmap,
+                                                          n_nulls);
+  return GARROW_LARGE_BINARY_ARRAY(large_binary_array);
 }
 
 /**
@@ -1639,13 +1877,8 @@ GBytes *
 garrow_large_binary_array_get_value(GArrowLargeBinaryArray *array,
                                     gint64 i)
 {
-  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
-  auto arrow_large_binary_array =
-    static_cast<arrow::LargeBinaryArray *>(arrow_array.get());
-
-  int64_t length;
-  auto value = arrow_large_binary_array->GetValue(i, &length);
-  return g_bytes_new_static(value, length);
+  return garrow_base_binary_array_get_value<arrow::LargeBinaryArray>(
+    GARROW_ARRAY(array), i);
 }
 
 /**
@@ -1655,15 +1888,28 @@ 
garrow_large_binary_array_get_value(GArrowLargeBinaryArray *array,
  * Returns: (transfer full): The data of the array as #GArrowBuffer.
  *
  * Since: 0.16.0
+ *
+ * Deprecated: 1.0.0: Use garrow_large_binary_array_get_data_buffer() instead.
  */
 GArrowBuffer *
 garrow_large_binary_array_get_buffer(GArrowLargeBinaryArray *array)
 {
-  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
-  auto arrow_large_binary_array =
-    static_cast<arrow::LargeBinaryArray *>(arrow_array.get());
-  auto arrow_data = arrow_large_binary_array->value_data();
-  return garrow_buffer_new_raw(&arrow_data);
+  return garrow_large_binary_array_get_data_buffer(array);
+}
+
+/**
+ * garrow_large_binary_array_get_data_buffer:
+ * @array: A #GArrowLargeBinaryArray.
+ *
+ * Returns: (transfer full): The data of the array as #GArrowBuffer.
+ *
+ * Since: 1.0.0
+ */
+GArrowBuffer *
+garrow_large_binary_array_get_data_buffer(GArrowLargeBinaryArray *array)
+{
+  return garrow_base_binary_array_get_data_buffer<arrow::LargeBinaryArray>(
+    GARROW_ARRAY(array));
 }
 
 /**
@@ -1677,14 +1923,25 @@ 
garrow_large_binary_array_get_buffer(GArrowLargeBinaryArray *array)
 GArrowBuffer *
 garrow_large_binary_array_get_offsets_buffer(GArrowLargeBinaryArray *array)
 {
-  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
-  auto arrow_large_binary_array =
-    static_cast<arrow::LargeBinaryArray *>(arrow_array.get());
-  auto arrow_offsets = arrow_large_binary_array->value_offsets();
-  return garrow_buffer_new_raw(&arrow_offsets);
+  return garrow_base_binary_array_get_offsets_buffer<arrow::LargeBinaryArray>(
+    GARROW_ARRAY(array));
 }
 
 
+G_END_DECLS
+template <typename STRING_ARRAY_CLASS>
+gchar *
+garrow_base_string_array_get_value(GArrowArray *array,
+                                   gint64 i)
+{
+  auto arrow_array = garrow_array_get_raw(array);
+  auto arrow_string_array =
+    std::static_pointer_cast<STRING_ARRAY_CLASS>(arrow_array);
+  auto view = arrow_string_array->GetView(i);
+  return g_strndup(view.data(), view.length());
+};
+G_BEGIN_DECLS
+
 G_DEFINE_TYPE(GArrowStringArray,
               garrow_string_array,
               GARROW_TYPE_BINARY_ARRAY)
@@ -1703,7 +1960,7 @@ garrow_string_array_class_init(GArrowStringArrayClass 
*klass)
  * garrow_string_array_new:
  * @length: The number of elements.
  * @value_offsets: The value offsets of @data in Arrow format.
- * @data: The binary data in Arrow format of the array.
+ * @value_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
@@ -1718,22 +1975,17 @@ garrow_string_array_class_init(GArrowStringArrayClass 
*klass)
 GArrowStringArray *
 garrow_string_array_new(gint64 length,
                         GArrowBuffer *value_offsets,
-                        GArrowBuffer *data,
+                        GArrowBuffer *value_data,
                         GArrowBuffer *null_bitmap,
                         gint64 n_nulls)
 {
-  const auto arrow_value_offsets = garrow_buffer_get_raw(value_offsets);
-  const auto arrow_data = garrow_buffer_get_raw(data);
-  const auto arrow_bitmap = garrow_buffer_get_raw(null_bitmap);
-  auto arrow_string_array =
-    std::make_shared<arrow::StringArray>(length,
-                                         arrow_value_offsets,
-                                         arrow_data,
-                                         arrow_bitmap,
-                                         n_nulls);
-  auto arrow_array =
-    std::static_pointer_cast<arrow::Array>(arrow_string_array);
-  return GARROW_STRING_ARRAY(garrow_array_new_raw(&arrow_array));
+  auto string_array =
+    garrow_base_binary_array_new<arrow::StringArray>(length,
+                                                     value_offsets,
+                                                     value_data,
+                                                     null_bitmap,
+                                                     n_nulls);
+  return GARROW_STRING_ARRAY(string_array);
 }
 
 /**
@@ -1747,13 +1999,8 @@ gchar *
 garrow_string_array_get_string(GArrowStringArray *array,
                                gint64 i)
 {
-  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
-  auto arrow_string_array =
-    static_cast<arrow::StringArray *>(arrow_array.get());
-  gint32 length;
-  auto value =
-    reinterpret_cast<const gchar *>(arrow_string_array->GetValue(i, &length));
-  return g_strndup(value, length);
+  return garrow_base_string_array_get_value<arrow::StringArray>(
+    GARROW_ARRAY(array), i);
 }
 
 
@@ -1775,7 +2022,7 @@ 
garrow_large_string_array_class_init(GArrowLargeStringArrayClass *klass)
  * garrow_large_string_array_new:
  * @length: The number of elements.
  * @value_offsets: The value offsets of @data in Arrow format.
- * @data: The binary data in Arrow format of the array.
+ * @value_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
@@ -1790,22 +2037,17 @@ 
garrow_large_string_array_class_init(GArrowLargeStringArrayClass *klass)
 GArrowLargeStringArray *
 garrow_large_string_array_new(gint64 length,
                               GArrowBuffer *value_offsets,
-                              GArrowBuffer *data,
+                              GArrowBuffer *value_data,
                               GArrowBuffer *null_bitmap,
                               gint64 n_nulls)
 {
-  const auto arrow_value_offsets = garrow_buffer_get_raw(value_offsets);
-  const auto arrow_data = garrow_buffer_get_raw(data);
-  const auto arrow_bitmap = garrow_buffer_get_raw(null_bitmap);
-  auto arrow_large_string_array =
-    std::make_shared<arrow::LargeStringArray>(length,
-                                              arrow_value_offsets,
-                                              arrow_data,
-                                              arrow_bitmap,
-                                              n_nulls);
-  auto arrow_array =
-    std::static_pointer_cast<arrow::Array>(arrow_large_string_array);
-  return GARROW_LARGE_STRING_ARRAY(garrow_array_new_raw(&arrow_array));
+  auto large_string_array =
+    garrow_base_binary_array_new<arrow::LargeStringArray>(length,
+                                                          value_offsets,
+                                                          value_data,
+                                                          null_bitmap,
+                                                          n_nulls);
+  return GARROW_LARGE_STRING_ARRAY(large_string_array);
 }
 
 /**
@@ -1821,13 +2063,8 @@ gchar *
 garrow_large_string_array_get_string(GArrowLargeStringArray *array,
                                      gint64 i)
 {
-  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
-  auto arrow_large_string_array =
-    static_cast<arrow::LargeStringArray *>(arrow_array.get());
-  gint64 length;
-  auto value =
-    reinterpret_cast<const gchar *>(arrow_large_string_array->GetValue(i, 
&length));
-  return g_strndup(value, length);
+  return garrow_base_string_array_get_value<arrow::LargeStringArray>(
+    GARROW_ARRAY(array), i);
 }
 
 
@@ -2310,8 +2547,31 @@ G_END_DECLS
 GArrowArray *
 garrow_array_new_raw(std::shared_ptr<arrow::Array> *arrow_array)
 {
+  return garrow_array_new_raw(arrow_array,
+                              "array", arrow_array,
+                              NULL);
+}
+
+GArrowArray *
+garrow_array_new_raw(std::shared_ptr<arrow::Array> *arrow_array,
+                     const gchar *first_property_name,
+                     ...)
+{
+  va_list args;
+  va_start(args, first_property_name);
+  auto array = garrow_array_new_raw_valist(arrow_array,
+                                           first_property_name,
+                                           args);
+  va_end(args);
+  return array;
+}
+
+GArrowArray *
+garrow_array_new_raw_valist(std::shared_ptr<arrow::Array> *arrow_array,
+                            const gchar *first_property_name,
+                            va_list args)
+{
   GType type;
-  GArrowArray *array;
 
   switch ((*arrow_array)->type_id()) {
   case arrow::Type::type::NA:
@@ -2410,10 +2670,9 @@ garrow_array_new_raw(std::shared_ptr<arrow::Array> 
*arrow_array)
     type = GARROW_TYPE_ARRAY;
     break;
   }
-  array = GARROW_ARRAY(g_object_new(type,
-                                    "array", arrow_array,
-                                    NULL));
-  return array;
+  return GARROW_ARRAY(g_object_new_valist(type,
+                                          first_property_name,
+                                          args));
 }
 
 std::shared_ptr<arrow::Array>
diff --git a/c_glib/arrow-glib/basic-array.h b/c_glib/arrow-glib/basic-array.h
index 3d7449a..ccb63db 100644
--- a/c_glib/arrow-glib/basic-array.h
+++ b/c_glib/arrow-glib/basic-array.h
@@ -94,7 +94,14 @@ struct _GArrowPrimitiveArrayClass
   GArrowArrayClass parent_class;
 };
 
-GArrowBuffer *garrow_primitive_array_get_buffer(GArrowPrimitiveArray *array);
+#ifndef GARROW_DISABLE_DEPRECATED
+GARROW_DEPRECATED_IN_1_0_FOR(garrow_primitive_array_get_data_buffer)
+GArrowBuffer *
+garrow_primitive_array_get_buffer(GArrowPrimitiveArray *array);
+#endif
+GARROW_AVAILABLE_IN_1_0
+GArrowBuffer *
+garrow_primitive_array_get_data_buffer(GArrowPrimitiveArray *array);
 
 
 #define GARROW_TYPE_BOOLEAN_ARRAY (garrow_boolean_array_get_type())
@@ -363,13 +370,18 @@ struct _GArrowBinaryArrayClass
 
 GArrowBinaryArray *garrow_binary_array_new(gint64 length,
                                            GArrowBuffer *value_offsets,
-                                           GArrowBuffer *data,
+                                           GArrowBuffer *value_data,
                                            GArrowBuffer *null_bitmap,
                                            gint64 n_nulls);
 
 GBytes *garrow_binary_array_get_value(GArrowBinaryArray *array,
                                       gint64 i);
+#ifndef GARROW_DISABLE_DEPRECATED
+GARROW_DEPRECATED_IN_1_0_FOR(garrow_binary_array_get_data_buffer)
 GArrowBuffer *garrow_binary_array_get_buffer(GArrowBinaryArray *array);
+#endif
+GARROW_AVAILABLE_IN_1_0
+GArrowBuffer *garrow_binary_array_get_data_buffer(GArrowBinaryArray *array);
 GArrowBuffer *garrow_binary_array_get_offsets_buffer(GArrowBinaryArray *array);
 
 
@@ -387,15 +399,22 @@ struct _GArrowLargeBinaryArrayClass
 GARROW_AVAILABLE_IN_0_16
 GArrowLargeBinaryArray *garrow_large_binary_array_new(gint64 length,
                                                       GArrowBuffer 
*value_offsets,
-                                                      GArrowBuffer *data,
+                                                      GArrowBuffer *value_data,
                                                       GArrowBuffer 
*null_bitmap,
                                                       gint64 n_nulls);
 
 GARROW_AVAILABLE_IN_0_16
 GBytes *garrow_large_binary_array_get_value(GArrowLargeBinaryArray *array,
                                             gint64 i);
+#ifndef GARROW_DISABLE_DEPRECATED
+GARROW_DEPRECATED_IN_1_0_FOR(garrow_large_binary_array_get_data_buffer)
 GARROW_AVAILABLE_IN_0_16
-GArrowBuffer *garrow_large_binary_array_get_buffer(GArrowLargeBinaryArray 
*array);
+GArrowBuffer *
+garrow_large_binary_array_get_buffer(GArrowLargeBinaryArray *array);
+#endif
+GARROW_AVAILABLE_IN_1_0
+GArrowBuffer *
+garrow_large_binary_array_get_data_buffer(GArrowLargeBinaryArray *array);
 GARROW_AVAILABLE_IN_0_16
 GArrowBuffer 
*garrow_large_binary_array_get_offsets_buffer(GArrowLargeBinaryArray *array);
 
@@ -413,7 +432,7 @@ struct _GArrowStringArrayClass
 
 GArrowStringArray *garrow_string_array_new(gint64 length,
                                            GArrowBuffer *value_offsets,
-                                           GArrowBuffer *data,
+                                           GArrowBuffer *value_data,
                                            GArrowBuffer *null_bitmap,
                                            gint64 n_nulls);
 
@@ -435,7 +454,7 @@ struct _GArrowLargeStringArrayClass
 GARROW_AVAILABLE_IN_0_16
 GArrowLargeStringArray *garrow_large_string_array_new(gint64 length,
                                                       GArrowBuffer 
*value_offsets,
-                                                      GArrowBuffer *data,
+                                                      GArrowBuffer *value_data,
                                                       GArrowBuffer 
*null_bitmap,
                                                       gint64 n_nulls);
 
diff --git a/c_glib/arrow-glib/basic-array.hpp 
b/c_glib/arrow-glib/basic-array.hpp
index 52b94a5..67915da 100644
--- a/c_glib/arrow-glib/basic-array.hpp
+++ b/c_glib/arrow-glib/basic-array.hpp
@@ -23,5 +23,15 @@
 
 #include <arrow-glib/basic-array.h>
 
-GArrowArray *garrow_array_new_raw(std::shared_ptr<arrow::Array> *arrow_array);
-std::shared_ptr<arrow::Array> garrow_array_get_raw(GArrowArray *array);
+GArrowArray *
+garrow_array_new_raw(std::shared_ptr<arrow::Array> *arrow_array);
+GArrowArray *
+garrow_array_new_raw(std::shared_ptr<arrow::Array> *arrow_array,
+                     const gchar *first_property_name,
+                     ...);
+GArrowArray *
+garrow_array_new_raw_valist(std::shared_ptr<arrow::Array> *arrow_array,
+                            const gchar *first_property_name,
+                            va_list args);
+std::shared_ptr<arrow::Array>
+garrow_array_get_raw(GArrowArray *array);
diff --git a/c_glib/arrow-glib/buffer.cpp b/c_glib/arrow-glib/buffer.cpp
index 3e9b721..f343d56 100644
--- a/c_glib/arrow-glib/buffer.cpp
+++ b/c_glib/arrow-glib/buffer.cpp
@@ -120,7 +120,16 @@ garrow_buffer_get_property(GObject *object,
                            GValue *value,
                            GParamSpec *pspec)
 {
-  G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+  auto priv = GARROW_BUFFER_GET_PRIVATE(object);
+
+  switch (prop_id) {
+  case PROP_PARENT:
+    g_value_set_object(value, priv->parent);
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
 }
 
 static void
@@ -161,7 +170,7 @@ garrow_buffer_class_init(GArrowBufferClass *klass)
                              "Parent",
                              "The parent GArrowBuffer *",
                              GARROW_TYPE_BUFFER,
-                             static_cast<GParamFlags>(G_PARAM_WRITABLE |
+                             static_cast<GParamFlags>(G_PARAM_READWRITE |
                                                       G_PARAM_CONSTRUCT_ONLY));
   g_object_class_install_property(gobject_class, PROP_PARENT, spec);
 }
diff --git a/c_glib/arrow-glib/composite-array.cpp 
b/c_glib/arrow-glib/composite-array.cpp
index 04b4d37..322c078 100644
--- a/c_glib/arrow-glib/composite-array.cpp
+++ b/c_glib/arrow-glib/composite-array.cpp
@@ -66,9 +66,131 @@ G_BEGIN_DECLS
  * normal array to dictionary array by garrow_array_dictionary_encode().
  */
 
-G_DEFINE_TYPE(GArrowListArray,
-              garrow_list_array,
-              GARROW_TYPE_ARRAY)
+typedef struct GArrowListArrayPrivate_ {
+  GArrowArray *raw_values;
+} GArrowListArrayPrivate;
+
+enum {
+  PROP_RAW_VALUES = 1,
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE(GArrowListArray,
+                           garrow_list_array,
+                           GARROW_TYPE_ARRAY)
+
+#define GARROW_LIST_ARRAY_GET_PRIVATE(obj)      \
+  static_cast<GArrowListArrayPrivate *>(        \
+    garrow_list_array_get_instance_private(     \
+      GARROW_LIST_ARRAY(obj)))
+
+G_END_DECLS
+template <typename LIST_ARRAY_CLASS>
+GArrowArray *
+garrow_base_list_array_new(GArrowDataType *data_type,
+                           gint64 length,
+                           GArrowBuffer *value_offsets,
+                           GArrowArray *values,
+                           GArrowBuffer *null_bitmap,
+                           gint64 n_nulls)
+{
+  const auto arrow_data_type = garrow_data_type_get_raw(data_type);
+  const auto arrow_value_offsets = garrow_buffer_get_raw(value_offsets);
+  const auto arrow_values = garrow_array_get_raw(values);
+  const auto arrow_null_bitmap = garrow_buffer_get_raw(null_bitmap);
+  auto arrow_list_array =
+    std::make_shared<LIST_ARRAY_CLASS>(arrow_data_type,
+                                       length,
+                                       arrow_value_offsets,
+                                       arrow_values,
+                                       arrow_null_bitmap,
+                                       n_nulls);
+  auto arrow_array =
+    std::static_pointer_cast<arrow::Array>(arrow_list_array);
+  return garrow_array_new_raw(&arrow_array,
+                              "array", &arrow_array,
+                              "value-data-type", data_type,
+                              "null-bitmap", null_bitmap,
+                              "buffer1", value_offsets,
+                              "raw-values", values,
+                              NULL);
+};
+
+template <typename LIST_ARRAY_CLASS>
+GArrowDataType *
+garrow_base_list_array_get_value_type(GArrowArray *array)
+{
+  auto arrow_array = garrow_array_get_raw(array);
+  auto arrow_list_array =
+    std::static_pointer_cast<LIST_ARRAY_CLASS>(arrow_array);
+  auto arrow_value_type = arrow_list_array->value_type();
+  return garrow_data_type_new_raw(&arrow_value_type);
+};
+
+template <typename LIST_ARRAY_CLASS>
+GArrowArray *
+garrow_base_list_array_get_value(GArrowArray *array,
+                                 gint64 i)
+{
+  auto arrow_array = garrow_array_get_raw(array);
+  auto arrow_list_array =
+    std::static_pointer_cast<LIST_ARRAY_CLASS>(arrow_array);
+  auto arrow_list = arrow_list_array->value_slice(i);
+  return garrow_array_new_raw(&arrow_list,
+                              "array", &arrow_list,
+                              "parent", array,
+                              NULL);
+};
+G_BEGIN_DECLS
+
+static void
+garrow_list_array_dispose(GObject *object)
+{
+  auto priv = GARROW_LIST_ARRAY_GET_PRIVATE(object);
+
+  if (priv->raw_values) {
+    g_object_unref(priv->raw_values);
+    priv->raw_values = NULL;
+  }
+
+
+  G_OBJECT_CLASS(garrow_list_array_parent_class)->dispose(object);
+}
+
+static void
+garrow_list_array_set_property(GObject *object,
+                               guint prop_id,
+                               const GValue *value,
+                               GParamSpec *pspec)
+{
+  auto priv = GARROW_LIST_ARRAY_GET_PRIVATE(object);
+
+  switch (prop_id) {
+  case PROP_RAW_VALUES:
+    priv->raw_values = GARROW_ARRAY(g_value_dup_object(value));
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
+}
+
+static void
+garrow_list_array_get_property(GObject *object,
+                               guint prop_id,
+                               GValue *value,
+                               GParamSpec *pspec)
+{
+  auto priv = GARROW_LIST_ARRAY_GET_PRIVATE(object);
+
+  switch (prop_id) {
+  case PROP_RAW_VALUES:
+    g_value_set_object(value, priv->raw_values);
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
+}
 
 static void
 garrow_list_array_init(GArrowListArray *object)
@@ -78,6 +200,20 @@ garrow_list_array_init(GArrowListArray *object)
 static void
 garrow_list_array_class_init(GArrowListArrayClass *klass)
 {
+  auto gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->dispose = garrow_list_array_dispose;
+  gobject_class->set_property = garrow_list_array_set_property;
+  gobject_class->get_property = garrow_list_array_get_property;
+
+  GParamSpec *spec;
+  spec = g_param_spec_object("raw-values",
+                             "Raw values",
+                             "The raw values",
+                             GARROW_TYPE_ARRAY,
+                             static_cast<GParamFlags>(G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_RAW_VALUES, spec);
 }
 
 /**
@@ -105,20 +241,14 @@ garrow_list_array_new(GArrowDataType *data_type,
                       GArrowBuffer *null_bitmap,
                       gint64 n_nulls)
 {
-  const auto arrow_data_type = garrow_data_type_get_raw(data_type);
-  const auto arrow_value_offsets = garrow_buffer_get_raw(value_offsets);
-  const auto arrow_values = garrow_array_get_raw(values);
-  const auto arrow_bitmap = garrow_buffer_get_raw(null_bitmap);
-  auto arrow_list_array =
-    std::make_shared<arrow::ListArray>(arrow_data_type,
-                                       length,
-                                       arrow_value_offsets,
-                                       arrow_values,
-                                       arrow_bitmap,
-                                       n_nulls);
-  auto arrow_array =
-    std::static_pointer_cast<arrow::Array>(arrow_list_array);
-  return GARROW_LIST_ARRAY(garrow_array_new_raw(&arrow_array));
+  auto list_array = garrow_base_list_array_new<arrow::ListArray>(
+    data_type,
+    length,
+    value_offsets,
+    values,
+    null_bitmap,
+    n_nulls);
+  return GARROW_LIST_ARRAY(list_array);
 }
 
 /**
@@ -130,11 +260,8 @@ garrow_list_array_new(GArrowDataType *data_type,
 GArrowDataType *
 garrow_list_array_get_value_type(GArrowListArray *array)
 {
-  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
-  auto arrow_list_array =
-    static_cast<arrow::ListArray *>(arrow_array.get());
-  auto arrow_value_type = arrow_list_array->value_type();
-  return garrow_data_type_new_raw(&arrow_value_type);
+  return garrow_base_list_array_get_value_type<arrow::ListArray>(
+    GARROW_ARRAY(array));
 }
 
 /**
@@ -148,19 +275,72 @@ GArrowArray *
 garrow_list_array_get_value(GArrowListArray *array,
                             gint64 i)
 {
-  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
-  auto arrow_list_array =
-    static_cast<arrow::ListArray *>(arrow_array.get());
-  auto arrow_list =
-    arrow_list_array->values()->Slice(arrow_list_array->value_offset(i),
-                                      arrow_list_array->value_length(i));
-  return garrow_array_new_raw(&arrow_list);
+  return garrow_base_list_array_get_value<arrow::ListArray>(
+    GARROW_ARRAY(array), i);
+}
+
+
+typedef struct GArrowLargeListArrayPrivate_ {
+  GArrowArray *raw_values;
+} GArrowLargeListArrayPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE(GArrowLargeListArray,
+                           garrow_large_list_array,
+                           GARROW_TYPE_ARRAY)
+
+#define GARROW_LARGE_LIST_ARRAY_GET_PRIVATE(obj)        \
+  static_cast<GArrowLargeListArrayPrivate *>(           \
+    garrow_large_list_array_get_instance_private(       \
+      GARROW_LARGE_LIST_ARRAY(obj)))
+
+static void
+garrow_large_list_array_dispose(GObject *object)
+{
+  auto priv = GARROW_LARGE_LIST_ARRAY_GET_PRIVATE(object);
+
+  if (priv->raw_values) {
+    g_object_unref(priv->raw_values);
+    priv->raw_values = NULL;
+  }
+
+  G_OBJECT_CLASS(garrow_large_list_array_parent_class)->dispose(object);
+}
+
+static void
+garrow_large_list_array_set_property(GObject *object,
+                                     guint prop_id,
+                                     const GValue *value,
+                                     GParamSpec *pspec)
+{
+  auto priv = GARROW_LARGE_LIST_ARRAY_GET_PRIVATE(object);
+
+  switch (prop_id) {
+  case PROP_RAW_VALUES:
+    priv->raw_values = GARROW_ARRAY(g_value_dup_object(value));
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
 }
 
+static void
+garrow_large_list_array_get_property(GObject *object,
+                                     guint prop_id,
+                                     GValue *value,
+                                     GParamSpec *pspec)
+{
+  auto priv = GARROW_LARGE_LIST_ARRAY_GET_PRIVATE(object);
 
-G_DEFINE_TYPE(GArrowLargeListArray,
-              garrow_large_list_array,
-              GARROW_TYPE_ARRAY)
+  switch (prop_id) {
+  case PROP_RAW_VALUES:
+    g_value_set_object(value, priv->raw_values);
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
+}
 
 static void
 garrow_large_list_array_init(GArrowLargeListArray *object)
@@ -170,6 +350,20 @@ garrow_large_list_array_init(GArrowLargeListArray *object)
 static void
 garrow_large_list_array_class_init(GArrowLargeListArrayClass *klass)
 {
+  auto gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->dispose = garrow_large_list_array_dispose;
+  gobject_class->set_property = garrow_large_list_array_set_property;
+  gobject_class->get_property = garrow_large_list_array_get_property;
+
+  GParamSpec *spec;
+  spec = g_param_spec_object("raw-values",
+                             "Raw values",
+                             "The raw values",
+                             GARROW_TYPE_ARRAY,
+                             static_cast<GParamFlags>(G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_RAW_VALUES, spec);
 }
 
 /**
@@ -197,20 +391,14 @@ garrow_large_list_array_new(GArrowDataType *data_type,
                             GArrowBuffer *null_bitmap,
                             gint64 n_nulls)
 {
-  const auto arrow_data_type = garrow_data_type_get_raw(data_type);
-  const auto arrow_value_offsets = garrow_buffer_get_raw(value_offsets);
-  const auto arrow_values = garrow_array_get_raw(values);
-  const auto arrow_bitmap = garrow_buffer_get_raw(null_bitmap);
-  auto arrow_large_list_array =
-    std::make_shared<arrow::LargeListArray>(arrow_data_type,
-                                            length,
-                                            arrow_value_offsets,
-                                            arrow_values,
-                                            arrow_bitmap,
-                                            n_nulls);
-  auto arrow_array =
-    std::static_pointer_cast<arrow::Array>(arrow_large_list_array);
-  return GARROW_LARGE_LIST_ARRAY(garrow_array_new_raw(&arrow_array));
+  auto large_list_array = garrow_base_list_array_new<arrow::LargeListArray>(
+    data_type,
+    length,
+    value_offsets,
+    values,
+    null_bitmap,
+    n_nulls);
+  return GARROW_LARGE_LIST_ARRAY(large_list_array);
 }
 
 /**
@@ -224,11 +412,8 @@ garrow_large_list_array_new(GArrowDataType *data_type,
 GArrowDataType *
 garrow_large_list_array_get_value_type(GArrowLargeListArray *array)
 {
-  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
-  auto arrow_large_list_array =
-    static_cast<arrow::LargeListArray *>(arrow_array.get());
-  auto arrow_value_type = arrow_large_list_array->value_type();
-  return garrow_data_type_new_raw(&arrow_value_type);
+  return garrow_base_list_array_get_value_type<arrow::LargeListArray>(
+    GARROW_ARRAY(array));
 }
 
 /**
@@ -244,18 +429,37 @@ GArrowArray *
 garrow_large_list_array_get_value(GArrowLargeListArray *array,
                                   gint64 i)
 {
-  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
-  auto arrow_large_list_array =
-    static_cast<arrow::LargeListArray *>(arrow_array.get());
-  auto arrow_large_list =
-    arrow_large_list_array->value_slice(i);
-  return garrow_array_new_raw(&arrow_large_list);
+  return garrow_base_list_array_get_value<arrow::LargeListArray>(
+    GARROW_ARRAY(array),
+    i);
 }
 
 
-G_DEFINE_TYPE(GArrowStructArray,
-              garrow_struct_array,
-              GARROW_TYPE_ARRAY)
+typedef struct GArrowStructArrayPrivate_ {
+  GPtrArray *fields;
+} GArrowStructArrayPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE(GArrowStructArray,
+                           garrow_struct_array,
+                           GARROW_TYPE_ARRAY)
+
+#define GARROW_STRUCT_ARRAY_GET_PRIVATE(obj)    \
+  static_cast<GArrowStructArrayPrivate *>(      \
+    garrow_struct_array_get_instance_private(   \
+      GARROW_STRUCT_ARRAY(obj)))
+
+static void
+garrow_struct_array_dispose(GObject *object)
+{
+  auto priv = GARROW_STRUCT_ARRAY_GET_PRIVATE(object);
+
+  if (priv->fields) {
+    g_ptr_array_free(priv->fields, TRUE);
+    priv->fields = NULL;
+  }
+
+  G_OBJECT_CLASS(garrow_struct_array_parent_class)->dispose(object);
+}
 
 static void
 garrow_struct_array_init(GArrowStructArray *object)
@@ -265,6 +469,8 @@ garrow_struct_array_init(GArrowStructArray *object)
 static void
 garrow_struct_array_class_init(GArrowStructArrayClass *klass)
 {
+  auto gobject_class = G_OBJECT_CLASS(klass);
+  gobject_class->dispose = garrow_struct_array_dispose;
 }
 
 /**
@@ -294,19 +500,49 @@ garrow_struct_array_new(GArrowDataType *data_type,
   const auto arrow_data_type = garrow_data_type_get_raw(data_type);
   std::vector<std::shared_ptr<arrow::Array>> arrow_fields;
   for (auto node = fields; node; node = node->next) {
-    auto child = GARROW_ARRAY(node->data);
-    arrow_fields.push_back(garrow_array_get_raw(child));
+    auto field = GARROW_ARRAY(node->data);
+    arrow_fields.push_back(garrow_array_get_raw(field));
   }
-  const auto arrow_bitmap = garrow_buffer_get_raw(null_bitmap);
+  const auto arrow_null_bitmap = garrow_buffer_get_raw(null_bitmap);
   auto arrow_struct_array =
     std::make_shared<arrow::StructArray>(arrow_data_type,
                                          length,
                                          arrow_fields,
-                                         arrow_bitmap,
+                                         arrow_null_bitmap,
                                          n_nulls);
   auto arrow_array =
     std::static_pointer_cast<arrow::Array>(arrow_struct_array);
-  return GARROW_STRUCT_ARRAY(garrow_array_new_raw(&arrow_array));
+  auto struct_array =
+    garrow_array_new_raw(&arrow_array,
+                         "array", &arrow_array,
+                         "null-bitmap", null_bitmap,
+                         NULL);
+  auto priv = GARROW_STRUCT_ARRAY_GET_PRIVATE(struct_array);
+  priv->fields = g_ptr_array_sized_new(arrow_fields.size());
+  g_ptr_array_set_free_func(priv->fields, g_object_unref);
+  for (auto node = fields; node; node = node->next) {
+    auto field = GARROW_ARRAY(node->data);
+    g_ptr_array_add(priv->fields, g_object_ref(field));
+  }
+  return GARROW_STRUCT_ARRAY(struct_array);
+}
+
+static GPtrArray *
+garrow_struct_array_get_fields_internal(GArrowStructArray *array)
+{
+  auto priv = GARROW_STRUCT_ARRAY_GET_PRIVATE(array);
+  if (!priv->fields) {
+    auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
+    auto arrow_struct_array =
+      std::static_pointer_cast<arrow::StructArray>(arrow_array);
+    auto arrow_fields = arrow_struct_array->fields();
+    priv->fields = g_ptr_array_sized_new(arrow_fields.size());
+    g_ptr_array_set_free_func(priv->fields, g_object_unref);
+    for (auto &arrow_field : arrow_fields) {
+      g_ptr_array_add(priv->fields, garrow_array_new_raw(&arrow_field));
+    }
+  }
+  return priv->fields;
 }
 
 /**
@@ -320,11 +556,19 @@ GArrowArray *
 garrow_struct_array_get_field(GArrowStructArray *array,
                               gint i)
 {
-  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
-  auto arrow_struct_array =
-    static_cast<arrow::StructArray *>(arrow_array.get());
-  auto arrow_field = arrow_struct_array->field(i);
-  return garrow_array_new_raw(&arrow_field);
+  auto fields = garrow_struct_array_get_fields_internal(array);
+  if (i < 0) {
+    i += fields->len;
+  }
+  if (i < 0) {
+    return NULL;
+  }
+  if (i >= static_cast<gint>(fields->len)) {
+    return NULL;
+  }
+  auto field = static_cast<GArrowArray *>(g_ptr_array_index(fields, i));
+  g_object_ref(field);
+  return field;
 }
 
 /**
@@ -333,13 +577,18 @@ garrow_struct_array_get_field(GArrowStructArray *array,
  *
  * Returns: (element-type GArrowArray) (transfer full):
  *   The fields in the struct.
- *
- * Deprecated: 0.10.0. Use garrow_struct_array_flatten() instead.
  */
 GList *
 garrow_struct_array_get_fields(GArrowStructArray *array)
 {
-  return garrow_struct_array_flatten(array, NULL);
+  auto fields = garrow_struct_array_get_fields_internal(array);
+
+  GList *field_list = NULL;
+  for (guint i = 0; i < fields->len; ++i) {
+    auto field = static_cast<GArrowArray *>(g_ptr_array_index(fields, i));
+    field_list = g_list_prepend(field_list, g_object_ref(field));
+  }
+  return g_list_reverse(field_list);
 }
 
 /**
@@ -375,9 +624,97 @@ garrow_struct_array_flatten(GArrowStructArray *array, 
GError **error)
 }
 
 
-G_DEFINE_TYPE(GArrowMapArray,
-              garrow_map_array,
-              GARROW_TYPE_LIST_ARRAY)
+typedef struct GArrowMapArrayPrivate_ {
+  GArrowArray *offsets;
+  GArrowArray *keys;
+  GArrowArray *items;
+} GArrowMapArrayPrivate;
+
+enum {
+  PROP_OFFSETS = 1,
+  PROP_KEYS,
+  PROP_ITEMS,
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE(GArrowMapArray,
+                           garrow_map_array,
+                           GARROW_TYPE_LIST_ARRAY)
+
+#define GARROW_MAP_ARRAY_GET_PRIVATE(obj)       \
+  static_cast<GArrowMapArrayPrivate *>(         \
+    garrow_map_array_get_instance_private(      \
+      GARROW_MAP_ARRAY(obj)))
+
+static void
+garrow_map_array_dispose(GObject *object)
+{
+  auto priv = GARROW_MAP_ARRAY_GET_PRIVATE(object);
+
+  if (priv->offsets) {
+    g_object_unref(priv->offsets);
+    priv->offsets = NULL;
+  }
+
+  if (priv->keys) {
+    g_object_unref(priv->keys);
+    priv->keys = NULL;
+  }
+
+  if (priv->items) {
+    g_object_unref(priv->items);
+    priv->items = NULL;
+  }
+
+  G_OBJECT_CLASS(garrow_map_array_parent_class)->dispose(object);
+}
+
+static void
+garrow_map_array_set_property(GObject *object,
+                              guint prop_id,
+                              const GValue *value,
+                              GParamSpec *pspec)
+{
+  auto priv = GARROW_MAP_ARRAY_GET_PRIVATE(object);
+
+  switch (prop_id) {
+  case PROP_OFFSETS:
+    priv->offsets = GARROW_ARRAY(g_value_dup_object(value));
+    break;
+  case PROP_KEYS:
+    priv->keys = GARROW_ARRAY(g_value_dup_object(value));
+    break;
+  case PROP_ITEMS:
+    priv->items = GARROW_ARRAY(g_value_dup_object(value));
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
+}
+
+static void
+garrow_map_array_get_property(GObject *object,
+                              guint prop_id,
+                              GValue *value,
+                              GParamSpec *pspec)
+{
+  auto priv = GARROW_MAP_ARRAY_GET_PRIVATE(object);
+
+  switch (prop_id) {
+  case PROP_OFFSETS:
+    g_value_set_object(value, priv->offsets);
+    break;
+  case PROP_KEYS:
+    g_value_set_object(value, priv->keys);
+    break;
+  case PROP_ITEMS:
+    g_value_set_object(value, priv->items);
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
+}
 
 static void
 garrow_map_array_init(GArrowMapArray *object)
@@ -387,6 +724,36 @@ garrow_map_array_init(GArrowMapArray *object)
 static void
 garrow_map_array_class_init(GArrowMapArrayClass *klass)
 {
+  auto gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->dispose = garrow_map_array_dispose;
+  gobject_class->set_property = garrow_map_array_set_property;
+  gobject_class->get_property = garrow_map_array_get_property;
+
+  GParamSpec *spec;
+  spec = g_param_spec_object("offsets",
+                             "Offsets",
+                             "The GArrowArray for offsets",
+                             GARROW_TYPE_ARRAY,
+                             static_cast<GParamFlags>(G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_OFFSETS, spec);
+
+  spec = g_param_spec_object("keys",
+                             "Keys",
+                             "The GArrowArray for keys",
+                             GARROW_TYPE_ARRAY,
+                             static_cast<GParamFlags>(G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_KEYS, spec);
+
+  spec = g_param_spec_object("items",
+                             "Items",
+                             "The GArrowArray for items",
+                             GARROW_TYPE_ARRAY,
+                             static_cast<GParamFlags>(G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_ITEMS, spec);
 }
 
 /**
@@ -411,12 +778,18 @@ garrow_map_array_new(GArrowArray *offsets,
   const auto arrow_keys = garrow_array_get_raw(keys);
   const auto arrow_items = garrow_array_get_raw(items);
   auto arrow_memory_pool = arrow::default_memory_pool();
-  auto arrow_array = arrow::MapArray::FromArrays(arrow_offsets,
-                                                 arrow_keys,
-                                                 arrow_items,
-                                                 arrow_memory_pool);
-  if (garrow::check(error, arrow_array, "[map-array][new]")) {
-    return GARROW_MAP_ARRAY(garrow_array_new_raw(&(*arrow_array)));
+  auto arrow_array_result = arrow::MapArray::FromArrays(arrow_offsets,
+                                                        arrow_keys,
+                                                        arrow_items,
+                                                        arrow_memory_pool);
+  if (garrow::check(error, arrow_array_result, "[map-array][new]")) {
+    auto arrow_array = *arrow_array_result;
+    return GARROW_MAP_ARRAY(garrow_array_new_raw(&arrow_array,
+                                                 "array", &arrow_array,
+                                                 "offsets", offsets,
+                                                 "keys", keys,
+                                                 "items", items,
+                                                 NULL));
   } else {
     return NULL;
   }
@@ -433,6 +806,12 @@ garrow_map_array_new(GArrowArray *offsets,
 GArrowArray *
 garrow_map_array_get_keys(GArrowMapArray *array)
 {
+  auto priv = GARROW_MAP_ARRAY_GET_PRIVATE(array);
+  if (priv->keys) {
+    g_object_ref(priv->keys);
+    return priv->keys;
+  }
+
   auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
   auto arrow_map_array =
     std::static_pointer_cast<arrow::MapArray>(arrow_array);
@@ -451,6 +830,12 @@ garrow_map_array_get_keys(GArrowMapArray *array)
 GArrowArray *
 garrow_map_array_get_items(GArrowMapArray *array)
 {
+  auto priv = GARROW_MAP_ARRAY_GET_PRIVATE(array);
+  if (priv->items) {
+    g_object_ref(priv->items);
+    return priv->items;
+  }
+
   auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
   auto arrow_map_array =
     std::static_pointer_cast<arrow::MapArray>(arrow_array);
@@ -459,9 +844,78 @@ garrow_map_array_get_items(GArrowMapArray *array)
 }
 
 
-G_DEFINE_TYPE(GArrowUnionArray,
-              garrow_union_array,
-              GARROW_TYPE_ARRAY)
+typedef struct GArrowUnionArrayPrivate_ {
+  GArrowInt8Array *type_ids;
+  GPtrArray *fields;
+} GArrowUnionArrayPrivate;
+
+enum {
+  PROP_TYPE_IDS = 1,
+  PROP_FIELDS,
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE(GArrowUnionArray,
+                           garrow_union_array,
+                           GARROW_TYPE_ARRAY)
+
+#define GARROW_UNION_ARRAY_GET_PRIVATE(obj)     \
+  static_cast<GArrowUnionArrayPrivate *>(       \
+    garrow_union_array_get_instance_private(    \
+      GARROW_UNION_ARRAY(obj)))
+
+static void
+garrow_union_array_dispose(GObject *object)
+{
+  auto priv = GARROW_UNION_ARRAY_GET_PRIVATE(object);
+
+  if (priv->type_ids) {
+    g_object_unref(priv->type_ids);
+    priv->type_ids = NULL;
+  }
+
+  if (priv->fields) {
+    g_ptr_array_free(priv->fields, TRUE);
+    priv->fields = NULL;
+  }
+
+  G_OBJECT_CLASS(garrow_union_array_parent_class)->dispose(object);
+}
+
+static void
+garrow_union_array_set_property(GObject *object,
+                                guint prop_id,
+                                const GValue *value,
+                                GParamSpec *pspec)
+{
+  auto priv = GARROW_UNION_ARRAY_GET_PRIVATE(object);
+
+  switch (prop_id) {
+  case PROP_TYPE_IDS:
+    priv->type_ids = GARROW_INT8_ARRAY(g_value_dup_object(value));
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
+}
+
+static void
+garrow_union_array_get_property(GObject *object,
+                                guint prop_id,
+                                GValue *value,
+                                GParamSpec *pspec)
+{
+  auto priv = GARROW_UNION_ARRAY_GET_PRIVATE(object);
+
+  switch (prop_id) {
+  case PROP_TYPE_IDS:
+    g_value_set_object(value, priv->type_ids);
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
+}
 
 static void
 garrow_union_array_init(GArrowUnionArray *object)
@@ -471,6 +925,20 @@ garrow_union_array_init(GArrowUnionArray *object)
 static void
 garrow_union_array_class_init(GArrowUnionArrayClass *klass)
 {
+  auto gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->dispose = garrow_union_array_dispose;
+  gobject_class->set_property = garrow_union_array_set_property;
+  gobject_class->get_property = garrow_union_array_get_property;
+
+  GParamSpec *spec;
+  spec = g_param_spec_object("type-ids",
+                             "Type IDs",
+                             "The GArrowInt8Array for type IDs",
+                             GARROW_TYPE_INT8_ARRAY,
+                             static_cast<GParamFlags>(G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_TYPE_IDS, spec);
 }
 
 /**
@@ -485,21 +953,32 @@ GArrowArray *
 garrow_union_array_get_field(GArrowUnionArray *array,
                              gint i)
 {
-  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
-  auto arrow_union_array =
-    std::static_pointer_cast<arrow::UnionArray>(arrow_array);
-  auto n_fields = arrow_array->num_fields();
+  auto priv = GARROW_UNION_ARRAY_GET_PRIVATE(array);
+  if (!priv->fields) {
+    auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
+    auto arrow_union_array =
+      std::static_pointer_cast<arrow::UnionArray>(arrow_array);
+    auto n_fields = arrow_union_array->num_fields();
+    priv->fields = g_ptr_array_sized_new(n_fields);
+    g_ptr_array_set_free_func(priv->fields, g_object_unref);
+    for (int i = 0; i < n_fields; ++i) {
+      auto arrow_field = arrow_union_array->field(i);
+      g_ptr_array_add(priv->fields, garrow_array_new_raw(&arrow_field));
+    }
+  }
+
   if (i < 0) {
-    i += n_fields;
+    i += priv->fields->len;
   }
   if (i < 0) {
     return NULL;
   }
-  if (i >= n_fields) {
+  if (i >= static_cast<gint>(priv->fields->len)) {
     return NULL;
   }
-  auto arrow_field_array = arrow_union_array->field(i);
-  return garrow_array_new_raw(&arrow_field_array);
+  auto field = static_cast<GArrowArray *>(g_ptr_array_index(priv->fields, i));
+  g_object_ref(field);
+  return field;
 }
 
 
@@ -517,6 +996,60 @@ 
garrow_sparse_union_array_class_init(GArrowSparseUnionArrayClass *klass)
 {
 }
 
+static GArrowSparseUnionArray *
+garrow_sparse_union_array_new_internal(GArrowSparseUnionDataType *data_type,
+                                       GArrowInt8Array *type_ids,
+                                       GList *fields,
+                                       GError **error,
+                                       const char *context)
+{
+  auto arrow_type_ids = garrow_array_get_raw(GARROW_ARRAY(type_ids));
+  std::vector<std::shared_ptr<arrow::Array>> arrow_fields;
+  for (auto node = fields; node; node = node->next) {
+    auto *field = GARROW_ARRAY(node->data);
+    arrow_fields.push_back(garrow_array_get_raw(field));
+  }
+  arrow::Result<std::shared_ptr<arrow::Array>> arrow_sparse_union_array_result;
+  if (data_type) {
+    auto arrow_data_type = 
garrow_data_type_get_raw(GARROW_DATA_TYPE(data_type));
+    auto arrow_union_data_type =
+      std::static_pointer_cast<arrow::UnionType>(arrow_data_type);
+    std::vector<std::string> arrow_field_names;
+    for (const auto &arrow_field : arrow_union_data_type->fields()) {
+      arrow_field_names.push_back(arrow_field->name());
+    }
+    arrow_sparse_union_array_result =
+      arrow::UnionArray::MakeSparse(*arrow_type_ids,
+                                    arrow_fields,
+                                    arrow_field_names,
+                                    arrow_union_data_type->type_codes());
+  } else {
+    arrow_sparse_union_array_result =
+      arrow::UnionArray::MakeSparse(*arrow_type_ids, arrow_fields);
+  }
+  if (garrow::check(error,
+                    arrow_sparse_union_array_result,
+                    context)) {
+    auto arrow_sparse_union_array = *arrow_sparse_union_array_result;
+    auto sparse_union_array =
+      garrow_array_new_raw(&arrow_sparse_union_array,
+                           "array", &arrow_sparse_union_array,
+                           "value-data-type", data_type,
+                           "type-ids", type_ids,
+                           NULL);
+    auto priv = GARROW_UNION_ARRAY_GET_PRIVATE(sparse_union_array);
+    priv->fields = g_ptr_array_sized_new(arrow_fields.size());
+    g_ptr_array_set_free_func(priv->fields, g_object_unref);
+    for (auto node = fields; node; node = node->next) {
+      auto field = GARROW_ARRAY(node->data);
+      g_ptr_array_add(priv->fields, g_object_ref(field));
+    }
+    return GARROW_SPARSE_UNION_ARRAY(sparse_union_array);
+  } else {
+    return NULL;
+  }
+}
+
 /**
  * garrow_sparse_union_array_new:
  * @type_ids: The field type IDs for each value as #GArrowInt8Array.
@@ -534,19 +1067,11 @@ garrow_sparse_union_array_new(GArrowInt8Array *type_ids,
                               GList *fields,
                               GError **error)
 {
-  auto arrow_type_ids = garrow_array_get_raw(GARROW_ARRAY(type_ids));
-  std::vector<std::shared_ptr<arrow::Array>> arrow_fields;
-  for (auto node = fields; node; node = node->next) {
-    auto *field = GARROW_ARRAY(node->data);
-    arrow_fields.push_back(garrow_array_get_raw(field));
-  }
-  auto arrow_union_array = arrow::UnionArray::MakeSparse(*arrow_type_ids,
-                                                         arrow_fields);
-  if (garrow::check(error, arrow_union_array, "[sparse-union-array][new]")) {
-    return 
GARROW_SPARSE_UNION_ARRAY(garrow_array_new_raw(&(*arrow_union_array)));
-  } else {
-    return NULL;
-  }
+  return garrow_sparse_union_array_new_internal(NULL,
+                                                type_ids,
+                                                fields,
+                                                error,
+                                                "[sparse-union-array][new]");
 }
 
 /**
@@ -568,33 +1093,80 @@ 
garrow_sparse_union_array_new_data_type(GArrowSparseUnionDataType *data_type,
                                         GList *fields,
                                         GError **error)
 {
-  auto arrow_data_type = garrow_data_type_get_raw(GARROW_DATA_TYPE(data_type));
-  auto arrow_union_data_type =
-    std::static_pointer_cast<arrow::UnionType>(arrow_data_type);
-  std::vector<std::string> arrow_field_names;
-  for (const auto &arrow_field : arrow_union_data_type->fields()) {
-    arrow_field_names.push_back(arrow_field->name());
-  }
-  auto arrow_type_ids = garrow_array_get_raw(GARROW_ARRAY(type_ids));
-  std::vector<std::shared_ptr<arrow::Array>> arrow_fields;
-  for (auto node = fields; node; node = node->next) {
-    auto *field = GARROW_ARRAY(node->data);
-    arrow_fields.push_back(garrow_array_get_raw(field));
+  return garrow_sparse_union_array_new_internal(
+    data_type,
+    type_ids,
+    fields,
+    error,
+    "[sparse-union-array][new][data-type]");
+}
+
+
+typedef struct GArrowDenseUnionArrayPrivate_ {
+  GArrowInt32Array *value_offsets;
+} GArrowDenseUnionArrayPrivate;
+
+enum {
+  PROP_VALUE_OFFSETS = 1,
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE(GArrowDenseUnionArray,
+                           garrow_dense_union_array,
+                           GARROW_TYPE_UNION_ARRAY)
+
+#define GARROW_DENSE_UNION_ARRAY_GET_PRIVATE(obj)       \
+  static_cast<GArrowDenseUnionArrayPrivate *>(          \
+    garrow_dense_union_array_get_instance_private(      \
+      GARROW_DENSE_UNION_ARRAY(obj)))
+
+static void
+garrow_dense_union_array_dispose(GObject *object)
+{
+  auto priv = GARROW_DENSE_UNION_ARRAY_GET_PRIVATE(object);
+
+  if (priv->value_offsets) {
+    g_object_unref(priv->value_offsets);
+    priv->value_offsets = NULL;
   }
-  auto arrow_union_array = arrow::UnionArray::MakeSparse(
-    *arrow_type_ids, arrow_fields, arrow_field_names,
-    arrow_union_data_type->type_codes());
-  if (garrow::check(error, arrow_union_array, 
"[sparse-union-array][new][data-type]")) {
-    return 
GARROW_SPARSE_UNION_ARRAY(garrow_array_new_raw(&(*arrow_union_array)));
-  } else {
-    return NULL;
+
+  G_OBJECT_CLASS(garrow_dense_union_array_parent_class)->dispose(object);
+}
+
+static void
+garrow_dense_union_array_set_property(GObject *object,
+                                      guint prop_id,
+                                      const GValue *value,
+                                      GParamSpec *pspec)
+{
+  auto priv = GARROW_DENSE_UNION_ARRAY_GET_PRIVATE(object);
+
+  switch (prop_id) {
+  case PROP_VALUE_OFFSETS:
+    priv->value_offsets = GARROW_INT32_ARRAY(g_value_dup_object(value));
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
   }
 }
 
+static void
+garrow_dense_union_array_get_property(GObject *object,
+                                      guint prop_id,
+                                      GValue *value,
+                                      GParamSpec *pspec)
+{
+  auto priv = GARROW_DENSE_UNION_ARRAY_GET_PRIVATE(object);
 
-G_DEFINE_TYPE(GArrowDenseUnionArray,
-              garrow_dense_union_array,
-              GARROW_TYPE_UNION_ARRAY)
+  switch (prop_id) {
+  case PROP_VALUE_OFFSETS:
+    g_value_set_object(value, priv->value_offsets);
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
+}
 
 static void
 garrow_dense_union_array_init(GArrowDenseUnionArray *object)
@@ -604,6 +1176,80 @@ garrow_dense_union_array_init(GArrowDenseUnionArray 
*object)
 static void
 garrow_dense_union_array_class_init(GArrowDenseUnionArrayClass *klass)
 {
+  auto gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->dispose = garrow_dense_union_array_dispose;
+  gobject_class->set_property = garrow_dense_union_array_set_property;
+  gobject_class->get_property = garrow_dense_union_array_get_property;
+
+  GParamSpec *spec;
+  spec = g_param_spec_object("value-offsets",
+                             "Value offsets",
+                             "The GArrowInt32Array for value offsets",
+                             GARROW_TYPE_INT32_ARRAY,
+                             static_cast<GParamFlags>(G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_VALUE_OFFSETS, spec);
+}
+
+static GArrowDenseUnionArray *
+garrow_dense_union_array_new_internal(GArrowDenseUnionDataType *data_type,
+                                      GArrowInt8Array *type_ids,
+                                      GArrowInt32Array *value_offsets,
+                                      GList *fields,
+                                      GError **error,
+                                      const gchar *context)
+{
+  auto arrow_type_ids = garrow_array_get_raw(GARROW_ARRAY(type_ids));
+  auto arrow_value_offsets = garrow_array_get_raw(GARROW_ARRAY(value_offsets));
+  std::vector<std::shared_ptr<arrow::Array>> arrow_fields;
+  for (auto node = fields; node; node = node->next) {
+    auto *field = GARROW_ARRAY(node->data);
+    arrow_fields.push_back(garrow_array_get_raw(field));
+  }
+  arrow::Result<std::shared_ptr<arrow::Array>> arrow_dense_union_array_result;
+  if (data_type) {
+    auto arrow_data_type = 
garrow_data_type_get_raw(GARROW_DATA_TYPE(data_type));
+    auto arrow_union_data_type =
+      std::static_pointer_cast<arrow::UnionType>(arrow_data_type);
+    std::vector<std::string> arrow_field_names;
+    for (const auto &arrow_field : arrow_union_data_type->fields()) {
+      arrow_field_names.push_back(arrow_field->name());
+    }
+    arrow_dense_union_array_result =
+      arrow::UnionArray::MakeDense(*arrow_type_ids,
+                                   *arrow_value_offsets,
+                                   arrow_fields,
+                                   arrow_field_names,
+                                   arrow_union_data_type->type_codes());
+  } else {
+    arrow_dense_union_array_result =
+      arrow::UnionArray::MakeDense(*arrow_type_ids,
+                                   *arrow_value_offsets,
+                                   arrow_fields);
+  }
+  if (garrow::check(error,
+                    arrow_dense_union_array_result,
+                    context)) {
+    auto arrow_dense_union_array = *arrow_dense_union_array_result;
+    auto dense_union_array =
+      garrow_array_new_raw(&arrow_dense_union_array,
+                           "array", &arrow_dense_union_array,
+                           "value-data-type", data_type,
+                           "type-ids", type_ids,
+                           "value-offsets", value_offsets,
+                           NULL);
+    auto priv = GARROW_UNION_ARRAY_GET_PRIVATE(dense_union_array);
+    priv->fields = g_ptr_array_sized_new(arrow_fields.size());
+    g_ptr_array_set_free_func(priv->fields, g_object_unref);
+    for (auto node = fields; node; node = node->next) {
+      auto field = GARROW_ARRAY(node->data);
+      g_ptr_array_add(priv->fields, g_object_ref(field));
+    }
+    return GARROW_DENSE_UNION_ARRAY(dense_union_array);
+  } else {
+    return NULL;
+  }
 }
 
 /**
@@ -626,21 +1272,12 @@ garrow_dense_union_array_new(GArrowInt8Array *type_ids,
                              GList *fields,
                              GError **error)
 {
-  auto arrow_type_ids = garrow_array_get_raw(GARROW_ARRAY(type_ids));
-  auto arrow_value_offsets = garrow_array_get_raw(GARROW_ARRAY(value_offsets));
-  std::vector<std::shared_ptr<arrow::Array>> arrow_fields;
-  for (auto node = fields; node; node = node->next) {
-    auto *field = GARROW_ARRAY(node->data);
-    arrow_fields.push_back(garrow_array_get_raw(field));
-  }
-  auto arrow_union_array = arrow::UnionArray::MakeDense(*arrow_type_ids,
-                                                        *arrow_value_offsets,
-                                                        arrow_fields);
-  if (garrow::check(error, arrow_union_array, "[dense-union-array][new]")) {
-    return 
GARROW_DENSE_UNION_ARRAY(garrow_array_new_raw(&(*arrow_union_array)));
-  } else {
-    return NULL;
-  }
+  return garrow_dense_union_array_new_internal(NULL,
+                                               type_ids,
+                                               value_offsets,
+                                               fields,
+                                               error,
+                                               "[dense-union-array][new]");
 }
 
 /**
@@ -665,34 +1302,94 @@ 
garrow_dense_union_array_new_data_type(GArrowDenseUnionDataType *data_type,
                                        GList *fields,
                                        GError **error)
 {
-  auto arrow_data_type = garrow_data_type_get_raw(GARROW_DATA_TYPE(data_type));
-  auto arrow_union_data_type =
-    std::static_pointer_cast<arrow::UnionType>(arrow_data_type);
-  std::vector<std::string> arrow_field_names;
-  for (const auto &arrow_field : arrow_union_data_type->fields()) {
-    arrow_field_names.push_back(arrow_field->name());
+  return garrow_dense_union_array_new_internal(
+    data_type,
+    type_ids,
+    value_offsets,
+    fields,
+    error,
+    "[dense-union-array][new][data-type]");
+}
+
+
+typedef struct GArrowDictionaryArrayPrivate_ {
+  GArrowArray *indices;
+  GArrowArray *dictionary;
+} GArrowDictionaryArrayPrivate;
+
+enum {
+  PROP_INDICES = 1,
+  PROP_DICTIONARY,
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE(GArrowDictionaryArray,
+                           garrow_dictionary_array,
+                           GARROW_TYPE_ARRAY)
+
+#define GARROW_DICTIONARY_ARRAY_GET_PRIVATE(obj)        \
+  static_cast<GArrowDictionaryArrayPrivate *>(          \
+    garrow_dictionary_array_get_instance_private(       \
+      GARROW_DICTIONARY_ARRAY(obj)))
+
+static void
+garrow_dictionary_array_dispose(GObject *object)
+{
+  auto priv = GARROW_DICTIONARY_ARRAY_GET_PRIVATE(object);
+
+  if (priv->indices) {
+    g_object_unref(priv->indices);
+    priv->indices = NULL;
   }
-  auto arrow_type_ids = garrow_array_get_raw(GARROW_ARRAY(type_ids));
-  auto arrow_value_offsets = garrow_array_get_raw(GARROW_ARRAY(value_offsets));
-  std::vector<std::shared_ptr<arrow::Array>> arrow_fields;
-  for (auto node = fields; node; node = node->next) {
-    auto *field = GARROW_ARRAY(node->data);
-    arrow_fields.push_back(garrow_array_get_raw(field));
+
+  if (priv->dictionary) {
+    g_object_unref(priv->dictionary);
+    priv->dictionary = NULL;
   }
-  auto arrow_union_array = arrow::UnionArray::MakeDense(
-    *arrow_type_ids, *arrow_value_offsets, arrow_fields, arrow_field_names,
-    arrow_union_data_type->type_codes());
-  if (garrow::check(error, arrow_union_array, 
"[dense-union-array][new][data-type]")) {
-    return 
GARROW_DENSE_UNION_ARRAY(garrow_array_new_raw(&(*arrow_union_array)));
-  } else {
-    return NULL;
+
+  G_OBJECT_CLASS(garrow_dictionary_array_parent_class)->dispose(object);
+}
+
+static void
+garrow_dictionary_array_set_property(GObject *object,
+                                     guint prop_id,
+                                     const GValue *value,
+                                     GParamSpec *pspec)
+{
+  auto priv = GARROW_DICTIONARY_ARRAY_GET_PRIVATE(object);
+
+  switch (prop_id) {
+  case PROP_INDICES:
+    priv->indices = GARROW_ARRAY(g_value_dup_object(value));
+    break;
+  case PROP_DICTIONARY:
+    priv->dictionary = GARROW_ARRAY(g_value_dup_object(value));
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
   }
 }
 
+static void
+garrow_dictionary_array_get_property(GObject *object,
+                                     guint prop_id,
+                                     GValue *value,
+                                     GParamSpec *pspec)
+{
+  auto priv = GARROW_DICTIONARY_ARRAY_GET_PRIVATE(object);
 
-G_DEFINE_TYPE(GArrowDictionaryArray,
-              garrow_dictionary_array,
-              GARROW_TYPE_ARRAY)
+  switch (prop_id) {
+  case PROP_INDICES:
+    g_value_set_object(value, priv->indices);
+    break;
+  case PROP_DICTIONARY:
+    g_value_set_object(value, priv->dictionary);
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
+}
 
 static void
 garrow_dictionary_array_init(GArrowDictionaryArray *object)
@@ -702,6 +1399,28 @@ garrow_dictionary_array_init(GArrowDictionaryArray 
*object)
 static void
 garrow_dictionary_array_class_init(GArrowDictionaryArrayClass *klass)
 {
+  auto gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->dispose = garrow_dictionary_array_dispose;
+  gobject_class->set_property = garrow_dictionary_array_set_property;
+  gobject_class->get_property = garrow_dictionary_array_get_property;
+
+  GParamSpec *spec;
+  spec = g_param_spec_object("indices",
+                             "The indices",
+                             "The GArrowArray for indices",
+                             GARROW_TYPE_ARRAY,
+                             static_cast<GParamFlags>(G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_INDICES, spec);
+
+  spec = g_param_spec_object("dictionary",
+                             "The dictionary",
+                             "The GArrowArray for dictionary",
+                             GARROW_TYPE_ARRAY,
+                             static_cast<GParamFlags>(G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_DICTIONARY, spec);
 }
 
 /**
@@ -725,12 +1444,23 @@ garrow_dictionary_array_new(GArrowDataType *data_type,
   const auto arrow_data_type = garrow_data_type_get_raw(data_type);
   const auto arrow_indices = garrow_array_get_raw(indices);
   const auto arrow_dictionary = garrow_array_get_raw(dictionary);
-  auto arrow_dictionary_array = arrow::DictionaryArray::FromArrays(
-    arrow_data_type, arrow_indices, arrow_dictionary);
-  if (garrow::check(error, arrow_dictionary_array, "[dictionary-array][new]")) 
{
+  auto arrow_dictionary_array_result =
+    arrow::DictionaryArray::FromArrays(
+      arrow_data_type,
+      arrow_indices,
+      arrow_dictionary);
+  if (garrow::check(error,
+                    arrow_dictionary_array_result,
+                    "[dictionary-array][new]")) {
     auto arrow_array =
-      std::static_pointer_cast<arrow::Array>(*arrow_dictionary_array);
-    return GARROW_DICTIONARY_ARRAY(garrow_array_new_raw(&arrow_array));
+      std::static_pointer_cast<arrow::Array>(*arrow_dictionary_array_result);
+    auto dictionary_array = garrow_array_new_raw(&arrow_array,
+                                                 "array", &arrow_array,
+                                                 "value-data-type", data_type,
+                                                 "indices", indices,
+                                                 "dictionary", dictionary,
+                                                 NULL);
+    return GARROW_DICTIONARY_ARRAY(dictionary_array);
   } else {
     return NULL;
   }
@@ -747,6 +1477,12 @@ garrow_dictionary_array_new(GArrowDataType *data_type,
 GArrowArray *
 garrow_dictionary_array_get_indices(GArrowDictionaryArray *array)
 {
+  auto priv = GARROW_DICTIONARY_ARRAY_GET_PRIVATE(array);
+  if (priv->indices) {
+    g_object_ref(priv->indices);
+    return priv->indices;
+  }
+
   auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
   auto arrow_dictionary_array =
     std::static_pointer_cast<arrow::DictionaryArray>(arrow_array);
@@ -765,6 +1501,12 @@ garrow_dictionary_array_get_indices(GArrowDictionaryArray 
*array)
 GArrowArray *
 garrow_dictionary_array_get_dictionary(GArrowDictionaryArray *array)
 {
+  auto priv = GARROW_DICTIONARY_ARRAY_GET_PRIVATE(array);
+  if (priv->dictionary) {
+    g_object_ref(priv->dictionary);
+    return priv->dictionary;
+  }
+
   auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
   auto arrow_dictionary_array =
     std::static_pointer_cast<arrow::DictionaryArray>(arrow_array);
@@ -779,24 +1521,13 @@ 
garrow_dictionary_array_get_dictionary(GArrowDictionaryArray *array)
  * Returns: (transfer full): The dictionary data type of this array.
  *
  * Since: 0.8.0
+ *
+ * Deprecated: 1.0.0: Use garrow_array_get_value_data_type() instead.
  */
 GArrowDictionaryDataType *
 garrow_dictionary_array_get_dictionary_data_type(GArrowDictionaryArray *array)
 {
-  auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
-  auto arrow_dictionary_array =
-    std::static_pointer_cast<arrow::DictionaryArray>(arrow_array);
-  auto arrow_dictionary_data_type = arrow_dictionary_array->dict_type();
-  auto const_arrow_data_type =
-    static_cast<const arrow::DataType *>(arrow_dictionary_data_type);
-  auto arrow_data_type = const_cast<arrow::DataType *>(const_arrow_data_type);
-  struct NullDeleter {
-    void operator()(arrow::DataType *data_type) {
-    }
-  };
-  std::shared_ptr<arrow::DataType>
-    shared_arrow_data_type(arrow_data_type, NullDeleter());
-  auto data_type = garrow_data_type_new_raw(&shared_arrow_data_type);
+  auto data_type = garrow_array_get_value_data_type(GARROW_ARRAY(array));
   return GARROW_DICTIONARY_DATA_TYPE(data_type);
 }
 
diff --git a/c_glib/arrow-glib/composite-array.h 
b/c_glib/arrow-glib/composite-array.h
index 8fde0c0..dd0c726 100644
--- a/c_glib/arrow-glib/composite-array.h
+++ b/c_glib/arrow-glib/composite-array.h
@@ -95,10 +95,7 @@ GArrowStructArray *garrow_struct_array_new(GArrowDataType 
*data_type,
 GArrowArray *garrow_struct_array_get_field(GArrowStructArray *array,
                                            gint i);
 
-#ifndef GARROW_DISABLE_DEPRECATED
-GARROW_DEPRECATED_IN_0_10_FOR(garrow_struct_array_flatten)
 GList *garrow_struct_array_get_fields(GArrowStructArray *array);
-#endif
 
 GARROW_AVAILABLE_IN_0_10
 GList *garrow_struct_array_flatten(GArrowStructArray *array, GError **error);
@@ -210,7 +207,10 @@ GArrowArray *
 garrow_dictionary_array_get_indices(GArrowDictionaryArray *array);
 GArrowArray *
 garrow_dictionary_array_get_dictionary(GArrowDictionaryArray *array);
+#ifndef GARROW_DISABLE_DEPRECATED
+GARROW_DEPRECATED_IN_1_0_FOR(garrow_array_get_value_data_type)
 GArrowDictionaryDataType *
 garrow_dictionary_array_get_dictionary_data_type(GArrowDictionaryArray *array);
+#endif
 
 G_END_DECLS

Reply via email to