summaryrefslogtreecommitdiffstats
path: root/src/arrow/c_glib/arrow-glib/composite-array.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/arrow/c_glib/arrow-glib/composite-array.cpp')
-rw-r--r--src/arrow/c_glib/arrow-glib/composite-array.cpp1706
1 files changed, 1706 insertions, 0 deletions
diff --git a/src/arrow/c_glib/arrow-glib/composite-array.cpp b/src/arrow/c_glib/arrow-glib/composite-array.cpp
new file mode 100644
index 000000000..fd777f586
--- /dev/null
+++ b/src/arrow/c_glib/arrow-glib/composite-array.cpp
@@ -0,0 +1,1706 @@
+/*
+ * 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.
+ */
+
+#include <arrow-glib/array.hpp>
+#include <arrow-glib/buffer.hpp>
+#include <arrow-glib/compute.hpp>
+#include <arrow-glib/data-type.hpp>
+#include <arrow-glib/error.hpp>
+#include <arrow-glib/type.hpp>
+
+G_BEGIN_DECLS
+
+/**
+ * SECTION: composite-array
+ * @section_id: composite-array-classes
+ * @title: Composite array classes
+ * @include: arrow-glib/arrow-glib.h
+ *
+ * #GArrowListArray is a class for list array. It can store zero or
+ * more list data. If you don't have Arrow format data, you need to
+ * use #GArrowListArrayBuilder to create a new array.
+ *
+ * #GArrowLargeListArray is a class for 64-bit offsets list array.
+ * It can store zero or more list data. If you don't have Arrow format data,
+ * you need to use #GArrowLargeListArrayBuilder to create a new array.
+ *
+ * #GArrowStructArray is a class for struct array. It can store zero
+ * or more structs. One struct has one or more fields. If you don't
+ * have Arrow format data, you need to use #GArrowStructArrayBuilder
+ * to create a new array.
+ *
+ * #GArrowMapArray is a class for map array. It can store
+ * data with keys and items.
+ *
+ * #GArrowUnionArray is a base class for union array. It can store
+ * zero or more unions. One union has one or more fields but one union
+ * can store only one field value.
+ *
+ * #GArrowDenseUnionArray is a class for dense union array.
+ *
+ * #GArrowSparseUnionArray is a class for sparse union array.
+ *
+ * #GArrowDictionaryArray is a class for dictionary array. It can
+ * store data with dictionary and indices. It's space effective than
+ * normal array when the array has many same values. You can convert a
+ * normal array to dictionary array by garrow_array_dictionary_encode().
+ */
+
+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);
+};
+
+template <typename LIST_ARRAY_CLASS>
+GArrowArray *
+garrow_base_list_array_get_values(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_values = arrow_list_array->values();
+ return garrow_array_new_raw(&arrow_values,
+ "array", &arrow_values,
+ "parent", array,
+ NULL);
+};
+
+template <typename LIST_ARRAY_CLASS>
+typename LIST_ARRAY_CLASS::offset_type
+garrow_base_list_array_get_value_offset(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);
+ return arrow_list_array->value_offset(i);
+};
+
+template <typename LIST_ARRAY_CLASS>
+typename LIST_ARRAY_CLASS::offset_type
+garrow_base_list_array_get_value_length(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);
+ return arrow_list_array->value_length(i);
+};
+
+template <typename LIST_ARRAY_CLASS>
+const typename LIST_ARRAY_CLASS::offset_type *
+garrow_base_list_array_get_value_offsets(GArrowArray *array, gint64 *n_offsets)
+{
+ auto arrow_array = garrow_array_get_raw(array);
+ *n_offsets = arrow_array->length() + 1;
+ auto arrow_list_array =
+ std::static_pointer_cast<LIST_ARRAY_CLASS>(arrow_array);
+ return arrow_list_array->raw_value_offsets();
+};
+
+
+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)
+{
+}
+
+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);
+}
+
+/**
+ * garrow_list_array_new:
+ * @data_type: The data type of the list.
+ * @length: The number of elements.
+ * @value_offsets: The offsets of @values in Arrow format.
+ * @values: The values as #GArrowArray.
+ * @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 #GArrowListArray.
+ *
+ * Since: 0.4.0
+ */
+GArrowListArray *
+garrow_list_array_new(GArrowDataType *data_type,
+ gint64 length,
+ GArrowBuffer *value_offsets,
+ GArrowArray *values,
+ GArrowBuffer *null_bitmap,
+ gint64 n_nulls)
+{
+ 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);
+}
+
+/**
+ * garrow_list_array_get_value_type:
+ * @array: A #GArrowListArray.
+ *
+ * Returns: (transfer full): The data type of value in each list.
+ */
+GArrowDataType *
+garrow_list_array_get_value_type(GArrowListArray *array)
+{
+ return garrow_base_list_array_get_value_type<arrow::ListArray>(
+ GARROW_ARRAY(array));
+}
+
+/**
+ * garrow_list_array_get_value:
+ * @array: A #GArrowListArray.
+ * @i: The index of the target value.
+ *
+ * Returns: (transfer full): The i-th list.
+ */
+GArrowArray *
+garrow_list_array_get_value(GArrowListArray *array,
+ gint64 i)
+{
+ return garrow_base_list_array_get_value<arrow::ListArray>(
+ GARROW_ARRAY(array), i);
+}
+
+/**
+ * garrow_list_array_get_values:
+ * @array: A #GArrowListArray.
+ *
+ * Returns: (transfer full): The array containing the list's values.
+ *
+ * Since: 2.0.0
+ */
+GArrowArray *
+garrow_list_array_get_values(GArrowListArray *array)
+{
+ return garrow_base_list_array_get_values<arrow::ListArray>(
+ GARROW_ARRAY(array));
+}
+
+/**
+ * garrow_list_array_get_offset:
+ * @array: A #GArrowListArray.
+ * @i: The index of the offset of the target value.
+ *
+ * Returns: The target offset in the array containing the list's values.
+ *
+ * Since: 2.0.0
+ */
+gint32
+garrow_list_array_get_value_offset(GArrowListArray *array, gint64 i)
+{
+ return garrow_base_list_array_get_value_offset<arrow::ListArray>(
+ GARROW_ARRAY(array), i);
+}
+
+/**
+ * garrow_list_array_get_value_length:
+ * @array: A #GArrowListArray.
+ * @i: The index of the length of the target value.
+ *
+ * Returns: The target length in the array containing the list's values.
+ *
+ * Since: 2.0.0
+ */
+gint32
+garrow_list_array_get_value_length(GArrowListArray *array, gint64 i)
+{
+ return garrow_base_list_array_get_value_length<arrow::ListArray>(
+ GARROW_ARRAY(array), i);
+}
+
+/**
+ * garrow_list_array_get_value_offsets:
+ * @array: A #GArrowListArray.
+ * @n_offsets: The number of offsets to be returned.
+ *
+ * Returns: (array length=n_offsets): The target offsets in the array
+ * containing the list's values.
+ *
+ * Since: 2.0.0
+ */
+const gint32 *
+garrow_list_array_get_value_offsets(GArrowListArray *array, gint64 *n_offsets)
+{
+ return garrow_base_list_array_get_value_offsets<arrow::ListArray>(
+ GARROW_ARRAY(array), n_offsets);
+}
+
+
+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);
+
+ 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)
+{
+}
+
+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);
+}
+
+/**
+ * garrow_large_list_array_new:
+ * @data_type: The data type of the list.
+ * @length: The number of elements.
+ * @value_offsets: The offsets of @values in Arrow format.
+ * @values: The values as #GArrowArray.
+ * @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 #GArrowLargeListArray.
+ *
+ * Since: 0.16.0
+ */
+GArrowLargeListArray *
+garrow_large_list_array_new(GArrowDataType *data_type,
+ gint64 length,
+ GArrowBuffer *value_offsets,
+ GArrowArray *values,
+ GArrowBuffer *null_bitmap,
+ gint64 n_nulls)
+{
+ 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);
+}
+
+/**
+ * garrow_large_list_array_get_value_type:
+ * @array: A #GArrowLargeListArray.
+ *
+ * Returns: (transfer full): The data type of value in each list.
+ *
+ * Since: 0.16.0
+ */
+GArrowDataType *
+garrow_large_list_array_get_value_type(GArrowLargeListArray *array)
+{
+ return garrow_base_list_array_get_value_type<arrow::LargeListArray>(
+ GARROW_ARRAY(array));
+}
+
+/**
+ * garrow_large_list_array_get_value:
+ * @array: A #GArrowLargeListArray.
+ * @i: The index of the target value.
+ *
+ * Returns: (transfer full): The @i-th list.
+ *
+ * Since: 0.16.0
+ */
+GArrowArray *
+garrow_large_list_array_get_value(GArrowLargeListArray *array,
+ gint64 i)
+{
+ return garrow_base_list_array_get_value<arrow::LargeListArray>(
+ GARROW_ARRAY(array),
+ i);
+}
+
+/**
+ * garrow_large_list_array_get_values:
+ * @array: A #GArrowLargeListArray.
+ *
+ * Returns: (transfer full): The array containing the list's values.
+ *
+ * Since: 2.0.0
+ */
+GArrowArray *
+garrow_large_list_array_get_values(GArrowLargeListArray *array)
+{
+ return garrow_base_list_array_get_values<arrow::LargeListArray>(
+ GARROW_ARRAY(array));
+}
+
+/**
+ * garrow_large_list_array_get_value_offset:
+ * @array: A #GArrowLargeListArray.
+ * @i: The index of the offset of the target value.
+ *
+ * Returns: The target offset in the array containing the list's values.
+ *
+ * Since: 2.0.0
+ */
+gint64
+garrow_large_list_array_get_value_offset(GArrowLargeListArray *array, gint64 i)
+{
+ return garrow_base_list_array_get_value_offset<arrow::LargeListArray>(
+ GARROW_ARRAY(array), i);
+}
+
+/**
+ * garrow_large_list_array_get_length:
+ * @array: A #GArrowLargeListArray.
+ * @i: The index of the length of the target value.
+ *
+ * Returns: The target length in the array containing the list's values.
+ *
+ * Since: 2.0.0
+ */
+gint64
+garrow_large_list_array_get_value_length(GArrowLargeListArray *array, gint64 i)
+{
+ return garrow_base_list_array_get_value_length<arrow::LargeListArray>(
+ GARROW_ARRAY(array), i);
+}
+
+/**
+ * garrow_large_list_array_get_value_offsets:
+ * @array: A #GArrowLargeListArray.
+ * @n_offsets: The number of offsets to be returned.
+ *
+ * Returns: (array length=n_offsets): The target offsets in the array
+ * containing the list's values.
+ *
+ * Since: 2.0.0
+ */
+const gint64 *
+garrow_large_list_array_get_value_offsets(GArrowLargeListArray *array,
+ gint64 *n_offsets)
+{
+ return garrow_base_list_array_get_value_offsets<arrow::LargeListArray>(
+ GARROW_ARRAY(array), n_offsets);
+}
+
+
+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)
+{
+}
+
+static void
+garrow_struct_array_class_init(GArrowStructArrayClass *klass)
+{
+ auto gobject_class = G_OBJECT_CLASS(klass);
+ gobject_class->dispose = garrow_struct_array_dispose;
+}
+
+/**
+ * garrow_struct_array_new:
+ * @data_type: The data type of the struct.
+ * @length: The number of elements.
+ * @fields: (element-type GArrowArray): The arrays for each field
+ * as #GList of #GArrowArray.
+ * @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 #GArrowStructArray.
+ *
+ * Since: 0.4.0
+ */
+GArrowStructArray *
+garrow_struct_array_new(GArrowDataType *data_type,
+ gint64 length,
+ GList *fields,
+ GArrowBuffer *null_bitmap,
+ gint64 n_nulls)
+{
+ 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 field = GARROW_ARRAY(node->data);
+ arrow_fields.push_back(garrow_array_get_raw(field));
+ }
+ 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_null_bitmap,
+ n_nulls);
+ auto arrow_array =
+ std::static_pointer_cast<arrow::Array>(arrow_struct_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;
+}
+
+/**
+ * garrow_struct_array_get_field
+ * @array: A #GArrowStructArray.
+ * @i: The index of the field in the struct.
+ *
+ * Returns: (transfer full): The i-th field.
+ */
+GArrowArray *
+garrow_struct_array_get_field(GArrowStructArray *array,
+ gint i)
+{
+ 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;
+}
+
+/**
+ * garrow_struct_array_get_fields
+ * @array: A #GArrowStructArray.
+ *
+ * Returns: (element-type GArrowArray) (transfer full):
+ * The fields in the struct.
+ */
+GList *
+garrow_struct_array_get_fields(GArrowStructArray *array)
+{
+ 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);
+}
+
+/**
+ * garrow_struct_array_flatten
+ * @array: A #GArrowStructArray.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (element-type GArrowArray) (transfer full):
+ * The fields in the struct.
+ *
+ * Since: 0.10.0
+ */
+GList *
+garrow_struct_array_flatten(GArrowStructArray *array, GError **error)
+{
+ const auto arrow_array = garrow_array_get_raw(GARROW_ARRAY(array));
+ auto arrow_struct_array =
+ std::static_pointer_cast<arrow::StructArray>(arrow_array);
+
+ auto memory_pool = arrow::default_memory_pool();
+ auto arrow_arrays = arrow_struct_array->Flatten(memory_pool);
+ if (!garrow::check(error, arrow_arrays, "[struct-array][flatten]")) {
+ return NULL;
+ }
+
+ GList *arrays = NULL;
+ for (auto arrow_array : *arrow_arrays) {
+ auto array = garrow_array_new_raw(&arrow_array);
+ arrays = g_list_prepend(arrays, array);
+ }
+
+ return g_list_reverse(arrays);
+}
+
+
+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)
+{
+}
+
+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);
+}
+
+/**
+ * garrow_map_array_new:
+ * @offsets: The offsets Array containing n + 1 offsets encoding length and size.
+ * @keys: The Array containing key values.
+ * @items: The items Array containing item values.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (nullable): A newly created #GArrowMapArray
+ * or %NULL on error.
+ *
+ * Since: 0.17.0
+ */
+GArrowMapArray *
+garrow_map_array_new(GArrowArray *offsets,
+ GArrowArray *keys,
+ GArrowArray *items,
+ GError **error)
+{
+ const auto arrow_offsets = garrow_array_get_raw(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_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;
+ }
+}
+
+/**
+ * garrow_map_array_get_keys:
+ * @array: A #GArrowMapArray.
+ *
+ * Returns: (transfer full): The Array containing key values.
+ *
+ * Since: 0.17.0
+ */
+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);
+ auto arrow_keys = arrow_map_array->keys();
+ return garrow_array_new_raw(&arrow_keys);
+}
+
+/**
+ * garrow_map_array_get_items:
+ * @array: A #GArrowMapArray.
+ *
+ * Returns: (transfer full): The items Array containing item values.
+ *
+ * Since: 0.17.0
+ */
+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);
+ auto arrow_items = arrow_map_array->items();
+ return garrow_array_new_raw(&arrow_items);
+}
+
+
+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)
+{
+}
+
+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);
+}
+
+/**
+ * garrow_union_array_get_field
+ * @array: A #GArrowUnionArray.
+ * @i: The index of the field in the union.
+ *
+ * Returns: (nullable) (transfer full): The i-th field values as a
+ * #GArrowArray or %NULL on out of range.
+ */
+GArrowArray *
+garrow_union_array_get_field(GArrowUnionArray *array,
+ gint i)
+{
+ 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 += priv->fields->len;
+ }
+ if (i < 0) {
+ return NULL;
+ }
+ if (i >= static_cast<gint>(priv->fields->len)) {
+ return NULL;
+ }
+ auto field = static_cast<GArrowArray *>(g_ptr_array_index(priv->fields, i));
+ g_object_ref(field);
+ return field;
+}
+
+
+G_DEFINE_TYPE(GArrowSparseUnionArray,
+ garrow_sparse_union_array,
+ GARROW_TYPE_UNION_ARRAY)
+
+static void
+garrow_sparse_union_array_init(GArrowSparseUnionArray *object)
+{
+}
+
+static void
+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::SparseUnionArray::Make(*arrow_type_ids,
+ arrow_fields,
+ arrow_field_names,
+ arrow_union_data_type->type_codes());
+ } else {
+ arrow_sparse_union_array_result =
+ arrow::SparseUnionArray::Make(*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.
+ * @fields: (element-type GArrowArray): The arrays for each field
+ * as #GList of #GArrowArray.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (nullable): A newly created #GArrowSparseUnionArray
+ * or %NULL on error.
+ *
+ * Since: 0.12.0
+ */
+GArrowSparseUnionArray *
+garrow_sparse_union_array_new(GArrowInt8Array *type_ids,
+ GList *fields,
+ GError **error)
+{
+ return garrow_sparse_union_array_new_internal(NULL,
+ type_ids,
+ fields,
+ error,
+ "[sparse-union-array][new]");
+}
+
+/**
+ * garrow_sparse_union_array_new_data_type:
+ * @data_type: The data type for the sparse array.
+ * @type_ids: The field type IDs for each value as #GArrowInt8Array.
+ * @fields: (element-type GArrowArray): The arrays for each field
+ * as #GList of #GArrowArray.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (nullable): A newly created #GArrowSparseUnionArray
+ * or %NULL on error.
+ *
+ * Since: 0.14.0
+ */
+GArrowSparseUnionArray *
+garrow_sparse_union_array_new_data_type(GArrowSparseUnionDataType *data_type,
+ GArrowInt8Array *type_ids,
+ GList *fields,
+ GError **error)
+{
+ 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;
+ }
+
+ 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);
+
+ 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)
+{
+}
+
+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::DenseUnionArray::Make(*arrow_type_ids,
+ *arrow_value_offsets,
+ arrow_fields,
+ arrow_field_names,
+ arrow_union_data_type->type_codes());
+ } else {
+ arrow_dense_union_array_result =
+ arrow::DenseUnionArray::Make(*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;
+ }
+}
+
+/**
+ * garrow_dense_union_array_new:
+ * @type_ids: The field type IDs for each value as #GArrowInt8Array.
+ * @value_offsets: The value offsets for each value as #GArrowInt32Array.
+ * Each offset is counted for each type.
+ * @fields: (element-type GArrowArray): The arrays for each field
+ * as #GList of #GArrowArray.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (nullable): A newly created #GArrowDenseUnionArray
+ * or %NULL on error.
+ *
+ * Since: 0.12.0
+ */
+GArrowDenseUnionArray *
+garrow_dense_union_array_new(GArrowInt8Array *type_ids,
+ GArrowInt32Array *value_offsets,
+ GList *fields,
+ GError **error)
+{
+ return garrow_dense_union_array_new_internal(NULL,
+ type_ids,
+ value_offsets,
+ fields,
+ error,
+ "[dense-union-array][new]");
+}
+
+/**
+ * garrow_dense_union_array_new_data_type:
+ * @data_type: The data type for the dense array.
+ * @type_ids: The field type IDs for each value as #GArrowInt8Array.
+ * @value_offsets: The value offsets for each value as #GArrowInt32Array.
+ * Each offset is counted for each type.
+ * @fields: (element-type GArrowArray): The arrays for each field
+ * as #GList of #GArrowArray.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (nullable): A newly created #GArrowSparseUnionArray
+ * or %NULL on error.
+ *
+ * Since: 0.14.0
+ */
+GArrowDenseUnionArray *
+garrow_dense_union_array_new_data_type(GArrowDenseUnionDataType *data_type,
+ GArrowInt8Array *type_ids,
+ GArrowInt32Array *value_offsets,
+ GList *fields,
+ GError **error)
+{
+ 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;
+ }
+
+ if (priv->dictionary) {
+ g_object_unref(priv->dictionary);
+ priv->dictionary = 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);
+
+ 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)
+{
+}
+
+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);
+}
+
+/**
+ * garrow_dictionary_array_new:
+ * @data_type: The data type of the dictionary array.
+ * @indices: The indices of values in dictionary.
+ * @dictionary: The dictionary of the dictionary array.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (nullable): A newly created #GArrowDictionaryArray
+ * or %NULL on error.
+ *
+ * Since: 0.8.0
+ */
+GArrowDictionaryArray *
+garrow_dictionary_array_new(GArrowDataType *data_type,
+ GArrowArray *indices,
+ GArrowArray *dictionary,
+ GError **error)
+{
+ 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_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_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;
+ }
+}
+
+/**
+ * garrow_dictionary_array_get_indices:
+ * @array: A #GArrowDictionaryArray.
+ *
+ * Returns: (transfer full): The indices of values in dictionary.
+ *
+ * Since: 0.8.0
+ */
+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);
+ auto arrow_indices = arrow_dictionary_array->indices();
+ return garrow_array_new_raw(&arrow_indices);
+}
+
+/**
+ * garrow_dictionary_array_get_dictionary:
+ * @array: A #GArrowDictionaryArray.
+ *
+ * Returns: (transfer full): The dictionary of this array.
+ *
+ * Since: 0.8.0
+ */
+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);
+ auto arrow_dictionary = arrow_dictionary_array->dictionary();
+ return garrow_array_new_raw(&arrow_dictionary);
+}
+
+/**
+ * garrow_dictionary_array_get_dictionary_data_type:
+ * @array: A #GArrowDictionaryArray.
+ *
+ * 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 data_type = garrow_array_get_value_data_type(GARROW_ARRAY(array));
+ return GARROW_DICTIONARY_DATA_TYPE(data_type);
+}
+
+G_END_DECLS