1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *   http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied.  See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 #  include <config.h>
22 #endif
23 
24 #include <arrow-glib/basic-array.hpp>
25 #include <arrow-glib/data-type.hpp>
26 #include <arrow-glib/enums.h>
27 #include <arrow-glib/error.hpp>
28 #include <arrow-glib/field.hpp>
29 #include <arrow-glib/type.hpp>
30 
31 G_BEGIN_DECLS
32 
33 /**
34  * SECTION: composite-data-type
35  * @section_id: composite-data-type-classes
36  * @title: Composite data type classes
37  * @include: arrow-glib/arrow-glib.h
38  *
39  * #GArrowListDataType is a class for list data type.
40  *
41  * #GArrowLargeListDataType is a class for 64-bit offsets list data type.
42  *
43  * #GArrowStructDataType is a class for struct data type.
44  *
45  * #GArrowMapDataType is a class for map data type.
46  *
47  * #GArrowUnionDataType is a base class for union data types.
48  *
49  * #GArrowSparseUnionDataType is a class for sparse union data type.
50  *
51  * #GArrowDenseUnionDataType is a class for dense union data type.
52  *
53  * #GArrowDictionaryDataType is a class for dictionary data type.
54  */
55 
G_DEFINE_TYPE(GArrowListDataType,garrow_list_data_type,GARROW_TYPE_DATA_TYPE)56 G_DEFINE_TYPE(GArrowListDataType,
57               garrow_list_data_type,
58               GARROW_TYPE_DATA_TYPE)
59 
60 static void
61 garrow_list_data_type_init(GArrowListDataType *object)
62 {
63 }
64 
65 static void
garrow_list_data_type_class_init(GArrowListDataTypeClass * klass)66 garrow_list_data_type_class_init(GArrowListDataTypeClass *klass)
67 {
68 }
69 
70 /**
71  * garrow_list_data_type_new:
72  * @field: The field of elements
73  *
74  * Returns: The newly created list data type.
75  */
76 GArrowListDataType *
garrow_list_data_type_new(GArrowField * field)77 garrow_list_data_type_new(GArrowField *field)
78 {
79   auto arrow_field = garrow_field_get_raw(field);
80   auto arrow_data_type =
81     std::make_shared<arrow::ListType>(arrow_field);
82 
83   GArrowListDataType *data_type =
84     GARROW_LIST_DATA_TYPE(g_object_new(GARROW_TYPE_LIST_DATA_TYPE,
85                                        "data-type", &arrow_data_type,
86                                        NULL));
87   return data_type;
88 }
89 
90 /**
91  * garrow_list_data_type_get_value_field:
92  * @list_data_type: A #GArrowListDataType.
93  *
94  * Returns: (transfer full): The field of value.
95  *
96  * Deprecated: 0.13.0:
97  *   Use garrow_list_data_type_get_field() instead.
98  */
99 GArrowField *
garrow_list_data_type_get_value_field(GArrowListDataType * list_data_type)100 garrow_list_data_type_get_value_field(GArrowListDataType *list_data_type)
101 {
102   return garrow_list_data_type_get_field(list_data_type);
103 }
104 
105 /**
106  * garrow_list_data_type_get_field:
107  * @list_data_type: A #GArrowListDataType.
108  *
109  * Returns: (transfer full): The field of value.
110  *
111  * Since: 0.13.0
112  */
113 GArrowField *
garrow_list_data_type_get_field(GArrowListDataType * list_data_type)114 garrow_list_data_type_get_field(GArrowListDataType *list_data_type)
115 {
116   auto data_type = GARROW_DATA_TYPE(list_data_type);
117   auto arrow_data_type = garrow_data_type_get_raw(data_type);
118   auto arrow_list_data_type =
119     static_cast<arrow::ListType *>(arrow_data_type.get());
120 
121   auto arrow_field = arrow_list_data_type->value_field();
122   return garrow_field_new_raw(&arrow_field, nullptr);
123 }
124 
125 
G_DEFINE_TYPE(GArrowLargeListDataType,garrow_large_list_data_type,GARROW_TYPE_DATA_TYPE)126 G_DEFINE_TYPE(GArrowLargeListDataType,
127               garrow_large_list_data_type,
128               GARROW_TYPE_DATA_TYPE)
129 
130 static void
131 garrow_large_list_data_type_init(GArrowLargeListDataType *object)
132 {
133 }
134 
135 static void
garrow_large_list_data_type_class_init(GArrowLargeListDataTypeClass * klass)136 garrow_large_list_data_type_class_init(GArrowLargeListDataTypeClass *klass)
137 {
138 }
139 
140 /**
141  * garrow_large_list_data_type_new:
142  * @field: The field of elements
143  *
144  * Returns: The newly created large list data type.
145  *
146  * Since: 0.16.0
147  */
148 GArrowLargeListDataType *
garrow_large_list_data_type_new(GArrowField * field)149 garrow_large_list_data_type_new(GArrowField *field)
150 {
151   auto arrow_field = garrow_field_get_raw(field);
152   auto arrow_data_type =
153     std::make_shared<arrow::LargeListType>(arrow_field);
154 
155   GArrowLargeListDataType *data_type =
156     GARROW_LARGE_LIST_DATA_TYPE(g_object_new(GARROW_TYPE_LARGE_LIST_DATA_TYPE,
157                                              "data-type", &arrow_data_type,
158                                              NULL));
159   return data_type;
160 }
161 
162 /**
163  * garrow_large_list_data_type_get_field:
164  * @large_list_data_type: A #GArrowLargeListDataType.
165  *
166  * Returns: (transfer full): The field of value.
167  *
168  * Since: 0.16.0
169  */
170 GArrowField *
garrow_large_list_data_type_get_field(GArrowLargeListDataType * large_list_data_type)171 garrow_large_list_data_type_get_field(GArrowLargeListDataType *large_list_data_type)
172 {
173   auto data_type = GARROW_DATA_TYPE(large_list_data_type);
174   auto arrow_data_type = garrow_data_type_get_raw(data_type);
175   auto arrow_large_list_data_type =
176     static_cast<arrow::LargeListType *>(arrow_data_type.get());
177 
178   auto arrow_field = arrow_large_list_data_type->value_field();
179   return garrow_field_new_raw(&arrow_field, nullptr);
180 }
181 
182 
G_DEFINE_TYPE(GArrowStructDataType,garrow_struct_data_type,GARROW_TYPE_DATA_TYPE)183 G_DEFINE_TYPE(GArrowStructDataType,
184               garrow_struct_data_type,
185               GARROW_TYPE_DATA_TYPE)
186 
187 static void
188 garrow_struct_data_type_init(GArrowStructDataType *object)
189 {
190 }
191 
192 static void
garrow_struct_data_type_class_init(GArrowStructDataTypeClass * klass)193 garrow_struct_data_type_class_init(GArrowStructDataTypeClass *klass)
194 {
195 }
196 
197 /**
198  * garrow_struct_data_type_new:
199  * @fields: (element-type GArrowField): The fields of the struct.
200  *
201  * Returns: The newly created struct data type.
202  */
203 GArrowStructDataType *
garrow_struct_data_type_new(GList * fields)204 garrow_struct_data_type_new(GList *fields)
205 {
206   std::vector<std::shared_ptr<arrow::Field>> arrow_fields;
207   for (auto *node = fields; node; node = g_list_next(node)) {
208     auto field = GARROW_FIELD(node->data);
209     auto arrow_field = garrow_field_get_raw(field);
210     arrow_fields.push_back(arrow_field);
211   }
212 
213   auto arrow_data_type = std::make_shared<arrow::StructType>(arrow_fields);
214   auto data_type = g_object_new(GARROW_TYPE_STRUCT_DATA_TYPE,
215                                 "data-type", &arrow_data_type,
216                                 NULL);
217   return GARROW_STRUCT_DATA_TYPE(data_type);
218 }
219 
220 /**
221  * garrow_struct_data_type_get_n_fields:
222  * @struct_data_type: A #GArrowStructDataType.
223  *
224  * Returns: The number of fields of the struct data type.
225  *
226  * Since: 0.12.0
227  */
228 gint
garrow_struct_data_type_get_n_fields(GArrowStructDataType * struct_data_type)229 garrow_struct_data_type_get_n_fields(GArrowStructDataType *struct_data_type)
230 {
231   auto arrow_data_type = garrow_data_type_get_raw(GARROW_DATA_TYPE(struct_data_type));
232   return arrow_data_type->num_fields();
233 }
234 
235 /**
236  * garrow_struct_data_type_get_fields:
237  * @struct_data_type: A #GArrowStructDataType.
238  *
239  * Returns: (transfer full) (element-type GArrowField):
240  *   The fields of the struct data type.
241  *
242  * Since: 0.12.0
243  */
244 GList *
garrow_struct_data_type_get_fields(GArrowStructDataType * struct_data_type)245 garrow_struct_data_type_get_fields(GArrowStructDataType *struct_data_type)
246 {
247   auto data_type = GARROW_DATA_TYPE(struct_data_type);
248   auto arrow_data_type = garrow_data_type_get_raw(data_type);
249   auto arrow_fields = arrow_data_type->fields();
250 
251   GList *fields = NULL;
252   for (auto arrow_field : arrow_fields) {
253     fields = g_list_prepend(fields, garrow_field_new_raw(&arrow_field, nullptr));
254   }
255   return g_list_reverse(fields);
256 }
257 
258 /**
259  * garrow_struct_data_type_get_field:
260  * @struct_data_type: A #GArrowStructDataType.
261  * @i: The index of the target field.
262  *
263  * Returns: (transfer full) (nullable):
264  *   The field at the index in the struct data type or %NULL on not found.
265  *
266  * Since: 0.12.0
267  */
268 GArrowField *
garrow_struct_data_type_get_field(GArrowStructDataType * struct_data_type,gint i)269 garrow_struct_data_type_get_field(GArrowStructDataType *struct_data_type,
270                                   gint i)
271 {
272   auto data_type = GARROW_DATA_TYPE(struct_data_type);
273   auto arrow_data_type = garrow_data_type_get_raw(data_type);
274 
275   if (i < 0) {
276     i += arrow_data_type->num_fields();
277   }
278   if (i < 0) {
279     return NULL;
280   }
281   if (i >= arrow_data_type->num_fields()) {
282     return NULL;
283   }
284 
285   auto arrow_field = arrow_data_type->field(i);
286   if (arrow_field) {
287     return garrow_field_new_raw(&arrow_field, nullptr);
288   } else {
289     return NULL;
290   }
291 }
292 
293 /**
294  * garrow_struct_data_type_get_field_by_name:
295  * @struct_data_type: A #GArrowStructDataType.
296  * @name: The name of the target field.
297  *
298  * Returns: (transfer full) (nullable):
299  *   The field that has the name in the struct data type or %NULL on not found.
300  *
301  * Since: 0.12.0
302  */
303 GArrowField *
garrow_struct_data_type_get_field_by_name(GArrowStructDataType * struct_data_type,const gchar * name)304 garrow_struct_data_type_get_field_by_name(GArrowStructDataType *struct_data_type,
305                                           const gchar *name)
306 {
307   auto data_type = GARROW_DATA_TYPE(struct_data_type);
308   auto arrow_data_type = garrow_data_type_get_raw(data_type);
309   auto arrow_struct_data_type =
310     std::static_pointer_cast<arrow::StructType>(arrow_data_type);
311 
312   auto arrow_field = arrow_struct_data_type->GetFieldByName(name);
313   if (arrow_field) {
314     return garrow_field_new_raw(&arrow_field, nullptr);
315   } else {
316     return NULL;
317   }
318 }
319 
320 /**
321  * garrow_struct_data_type_get_field_index:
322  * @struct_data_type: A #GArrowStructDataType.
323  * @name: The name of the target field.
324  *
325  * Returns: The index of the target index in the struct data type
326  *   or `-1` on not found.
327  *
328  * Since: 0.12.0
329  */
330 gint
garrow_struct_data_type_get_field_index(GArrowStructDataType * struct_data_type,const gchar * name)331 garrow_struct_data_type_get_field_index(GArrowStructDataType *struct_data_type,
332                                         const gchar *name)
333 {
334   auto arrow_data_type = garrow_data_type_get_raw(GARROW_DATA_TYPE(struct_data_type));
335   auto arrow_struct_data_type =
336     std::static_pointer_cast<arrow::StructType>(arrow_data_type);
337 
338   return arrow_struct_data_type->GetFieldIndex(name);
339 }
340 
341 
G_DEFINE_TYPE(GArrowMapDataType,garrow_map_data_type,GARROW_TYPE_LIST_DATA_TYPE)342 G_DEFINE_TYPE(GArrowMapDataType,
343               garrow_map_data_type,
344               GARROW_TYPE_LIST_DATA_TYPE)
345 
346 static void
347 garrow_map_data_type_init(GArrowMapDataType *object)
348 {
349 }
350 
351 static void
garrow_map_data_type_class_init(GArrowMapDataTypeClass * klass)352 garrow_map_data_type_class_init(GArrowMapDataTypeClass *klass)
353 {
354 }
355 
356 /**
357  * garrow_map_data_type_new:
358  * @key_type: The key type of the map.
359  * @item_type: The item type of the map.
360  *
361  * Returns: The newly created map data type.
362  *
363  * Since: 0.17.0
364  */
365 GArrowMapDataType *
garrow_map_data_type_new(GArrowDataType * key_type,GArrowDataType * item_type)366 garrow_map_data_type_new(GArrowDataType *key_type,
367                          GArrowDataType *item_type)
368 {
369   auto arrow_key_type = garrow_data_type_get_raw(key_type);
370   auto arrow_item_type = garrow_data_type_get_raw(item_type);
371   auto arrow_data_type = std::make_shared<arrow::MapType>(arrow_key_type,
372                                                           arrow_item_type);
373   auto data_type = g_object_new(GARROW_TYPE_MAP_DATA_TYPE,
374                                 "data-type", &arrow_data_type,
375                                 NULL);
376   return GARROW_MAP_DATA_TYPE(data_type);
377 }
378 
379 /**
380  * garrow_map_data_type_get_key_type:
381  * @map_data_type: A #GArrowMapDataType.
382  *
383  * Return: (transfer full): The key type of the map.
384  *
385  * Since: 0.17.0
386  */
387 GArrowDataType *
garrow_map_data_type_get_key_type(GArrowMapDataType * map_data_type)388 garrow_map_data_type_get_key_type(GArrowMapDataType *map_data_type)
389 {
390   auto data_type = GARROW_DATA_TYPE(map_data_type);
391   auto arrow_data_type = garrow_data_type_get_raw(data_type);
392   auto arrow_map_data_type =
393     std::static_pointer_cast<arrow::MapType>(arrow_data_type);
394   auto arrow_key_type = arrow_map_data_type->key_type();
395   return garrow_data_type_new_raw(&arrow_key_type);
396 }
397 
398 /**
399  * garrow_map_data_type_get_item_type:
400  * @map_data_type: A #GArrowMapDataType.
401  *
402  * Return: (transfer full): The item type of the map.
403  *
404  * Since: 0.17.0
405  */
406 GArrowDataType *
garrow_map_data_type_get_item_type(GArrowMapDataType * map_data_type)407 garrow_map_data_type_get_item_type(GArrowMapDataType *map_data_type)
408 {
409   auto data_type = GARROW_DATA_TYPE(map_data_type);
410   auto arrow_data_type = garrow_data_type_get_raw(data_type);
411   auto arrow_map_data_type =
412     std::static_pointer_cast<arrow::MapType>(arrow_data_type);
413   auto arrow_item_type = arrow_map_data_type->item_type();
414   return garrow_data_type_new_raw(&arrow_item_type);
415 }
416 
417 
G_DEFINE_ABSTRACT_TYPE(GArrowUnionDataType,garrow_union_data_type,GARROW_TYPE_DATA_TYPE)418 G_DEFINE_ABSTRACT_TYPE(GArrowUnionDataType,
419                        garrow_union_data_type,
420                        GARROW_TYPE_DATA_TYPE)
421 
422 static void
423 garrow_union_data_type_init(GArrowUnionDataType *object)
424 {
425 }
426 
427 static void
garrow_union_data_type_class_init(GArrowUnionDataTypeClass * klass)428 garrow_union_data_type_class_init(GArrowUnionDataTypeClass *klass)
429 {
430 }
431 
432 /**
433  * garrow_union_data_type_get_n_fields:
434  * @union_data_type: A #GArrowUnionDataType.
435  *
436  * Returns: The number of fields of the union data type.
437  *
438  * Since: 0.12.0
439  */
440 gint
garrow_union_data_type_get_n_fields(GArrowUnionDataType * union_data_type)441 garrow_union_data_type_get_n_fields(GArrowUnionDataType *union_data_type)
442 {
443   auto arrow_data_type = garrow_data_type_get_raw(GARROW_DATA_TYPE(union_data_type));
444   return arrow_data_type->num_fields();
445 }
446 
447 /**
448  * garrow_union_data_type_get_fields:
449  * @union_data_type: A #GArrowUnionDataType.
450  *
451  * Returns: (transfer full) (element-type GArrowField):
452  *   The fields of the union data type.
453  *
454  * Since: 0.12.0
455  */
456 GList *
garrow_union_data_type_get_fields(GArrowUnionDataType * union_data_type)457 garrow_union_data_type_get_fields(GArrowUnionDataType *union_data_type)
458 {
459   auto data_type = GARROW_DATA_TYPE(union_data_type);
460   auto arrow_data_type = garrow_data_type_get_raw(data_type);
461   auto arrow_fields = arrow_data_type->fields();
462 
463   GList *fields = NULL;
464   for (auto arrow_field : arrow_fields) {
465     fields = g_list_prepend(fields, garrow_field_new_raw(&arrow_field, nullptr));
466   }
467   return g_list_reverse(fields);
468 }
469 
470 /**
471  * garrow_union_data_type_get_field:
472  * @union_data_type: A #GArrowUnionDataType.
473  * @i: The index of the target field.
474  *
475  * Returns: (transfer full) (nullable):
476  *   The field at the index in the union data type or %NULL on not found.
477  *
478  * Since: 0.12.0
479  */
480 GArrowField *
garrow_union_data_type_get_field(GArrowUnionDataType * union_data_type,gint i)481 garrow_union_data_type_get_field(GArrowUnionDataType *union_data_type,
482                                  gint i)
483 {
484   auto data_type = GARROW_DATA_TYPE(union_data_type);
485   auto arrow_data_type = garrow_data_type_get_raw(data_type);
486 
487   if (i < 0) {
488     i += arrow_data_type->num_fields();
489   }
490   if (i < 0) {
491     return NULL;
492   }
493   if (i >= arrow_data_type->num_fields()) {
494     return NULL;
495   }
496 
497   auto arrow_field = arrow_data_type->field(i);
498   if (arrow_field) {
499     return garrow_field_new_raw(&arrow_field, nullptr);
500   } else {
501     return NULL;
502   }
503 }
504 
505 /**
506  * garrow_union_data_type_get_type_codes:
507  * @union_data_type: A #GArrowUnionDataType.
508  * @n_type_codes: (out): The number of type codes.
509  *
510  * Returns: (transfer full) (array length=n_type_codes):
511  *   The codes for each field.
512  *
513  *   It should be freed with g_free() when no longer needed.
514  *
515  * Since: 0.12.0
516  */
517 gint8 *
garrow_union_data_type_get_type_codes(GArrowUnionDataType * union_data_type,gsize * n_type_codes)518 garrow_union_data_type_get_type_codes(GArrowUnionDataType *union_data_type,
519                                       gsize *n_type_codes)
520 {
521   auto arrow_data_type = garrow_data_type_get_raw(GARROW_DATA_TYPE(union_data_type));
522   auto arrow_union_data_type =
523     std::static_pointer_cast<arrow::UnionType>(arrow_data_type);
524 
525   const auto arrow_type_codes = arrow_union_data_type->type_codes();
526   const auto n = arrow_type_codes.size();
527   auto type_codes = static_cast<gint8 *>(g_new(gint8, n));
528   for (size_t i = 0; i < n; ++i) {
529     type_codes[i] = arrow_type_codes[i];
530   }
531   *n_type_codes = n;
532   return type_codes;
533 }
534 
535 
G_DEFINE_TYPE(GArrowSparseUnionDataType,garrow_sparse_union_data_type,GARROW_TYPE_UNION_DATA_TYPE)536 G_DEFINE_TYPE(GArrowSparseUnionDataType,
537               garrow_sparse_union_data_type,
538               GARROW_TYPE_UNION_DATA_TYPE)
539 
540 static void
541 garrow_sparse_union_data_type_init(GArrowSparseUnionDataType *object)
542 {
543 }
544 
545 static void
garrow_sparse_union_data_type_class_init(GArrowSparseUnionDataTypeClass * klass)546 garrow_sparse_union_data_type_class_init(GArrowSparseUnionDataTypeClass *klass)
547 {
548 }
549 
550 /**
551  * garrow_sparse_union_data_type_new:
552  * @fields: (element-type GArrowField): The fields of the union.
553  * @type_codes: (array length=n_type_codes): The codes to specify each field.
554  * @n_type_codes: The number of type codes.
555  *
556  * Returns: The newly created sparse union data type.
557  */
558 GArrowSparseUnionDataType *
garrow_sparse_union_data_type_new(GList * fields,gint8 * type_codes,gsize n_type_codes)559 garrow_sparse_union_data_type_new(GList *fields,
560                                   gint8 *type_codes,
561                                   gsize n_type_codes)
562 {
563   std::vector<std::shared_ptr<arrow::Field>> arrow_fields;
564   for (auto node = fields; node; node = g_list_next(node)) {
565     auto field = GARROW_FIELD(node->data);
566     auto arrow_field = garrow_field_get_raw(field);
567     arrow_fields.push_back(arrow_field);
568   }
569 
570   std::vector<int8_t> arrow_type_codes;
571   for (gsize i = 0; i < n_type_codes; ++i) {
572     arrow_type_codes.push_back(type_codes[i]);
573   }
574 
575   auto arrow_data_type =
576     std::make_shared<arrow::UnionType>(arrow_fields,
577                                        arrow_type_codes,
578                                        arrow::UnionMode::SPARSE);
579   auto data_type = g_object_new(GARROW_TYPE_SPARSE_UNION_DATA_TYPE,
580                                 "data-type", &arrow_data_type,
581                                 NULL);
582   return GARROW_SPARSE_UNION_DATA_TYPE(data_type);
583 }
584 
585 
G_DEFINE_TYPE(GArrowDenseUnionDataType,garrow_dense_union_data_type,GARROW_TYPE_UNION_DATA_TYPE)586 G_DEFINE_TYPE(GArrowDenseUnionDataType,
587               garrow_dense_union_data_type,
588               GARROW_TYPE_UNION_DATA_TYPE)
589 
590 static void
591 garrow_dense_union_data_type_init(GArrowDenseUnionDataType *object)
592 {
593 }
594 
595 static void
garrow_dense_union_data_type_class_init(GArrowDenseUnionDataTypeClass * klass)596 garrow_dense_union_data_type_class_init(GArrowDenseUnionDataTypeClass *klass)
597 {
598 }
599 
600 /**
601  * garrow_dense_union_data_type_new:
602  * @fields: (element-type GArrowField): The fields of the union.
603  * @type_codes: (array length=n_type_codes): The codes to specify each field.
604  * @n_type_codes: The number of type codes.
605  *
606  * Returns: The newly created dense union data type.
607  */
608 GArrowDenseUnionDataType *
garrow_dense_union_data_type_new(GList * fields,gint8 * type_codes,gsize n_type_codes)609 garrow_dense_union_data_type_new(GList *fields,
610                                  gint8 *type_codes,
611                                  gsize n_type_codes)
612 {
613   std::vector<std::shared_ptr<arrow::Field>> arrow_fields;
614   for (auto node = fields; node; node = g_list_next(node)) {
615     auto field = GARROW_FIELD(node->data);
616     auto arrow_field = garrow_field_get_raw(field);
617     arrow_fields.push_back(arrow_field);
618   }
619 
620   std::vector<int8_t> arrow_type_codes;
621   for (gsize i = 0; i < n_type_codes; ++i) {
622     arrow_type_codes.push_back(type_codes[i]);
623   }
624 
625   auto arrow_data_type =
626     std::make_shared<arrow::UnionType>(arrow_fields,
627                                        arrow_type_codes,
628                                        arrow::UnionMode::DENSE);
629   auto data_type = g_object_new(GARROW_TYPE_DENSE_UNION_DATA_TYPE,
630                                 "data-type", &arrow_data_type,
631                                 NULL);
632   return GARROW_DENSE_UNION_DATA_TYPE(data_type);
633 }
634 
635 
G_DEFINE_TYPE(GArrowDictionaryDataType,garrow_dictionary_data_type,GARROW_TYPE_FIXED_WIDTH_DATA_TYPE)636 G_DEFINE_TYPE(GArrowDictionaryDataType,
637               garrow_dictionary_data_type,
638               GARROW_TYPE_FIXED_WIDTH_DATA_TYPE)
639 
640 static void
641 garrow_dictionary_data_type_init(GArrowDictionaryDataType *object)
642 {
643 }
644 
645 static void
garrow_dictionary_data_type_class_init(GArrowDictionaryDataTypeClass * klass)646 garrow_dictionary_data_type_class_init(GArrowDictionaryDataTypeClass *klass)
647 {
648 }
649 
650 /**
651  * garrow_dictionary_data_type_new:
652  * @index_data_type: The data type of index.
653  * @value_data_type: The data type of dictionary values.
654  * @ordered: Whether dictionary contents are ordered or not.
655  *
656  * Returns: The newly created dictionary data type.
657  *
658  * Since: 0.8.0
659  */
660 GArrowDictionaryDataType *
garrow_dictionary_data_type_new(GArrowDataType * index_data_type,GArrowDataType * value_data_type,gboolean ordered)661 garrow_dictionary_data_type_new(GArrowDataType *index_data_type,
662                                 GArrowDataType *value_data_type,
663                                 gboolean ordered)
664 {
665   auto arrow_index_data_type = garrow_data_type_get_raw(index_data_type);
666   auto arrow_value_data_type = garrow_data_type_get_raw(value_data_type);
667   auto arrow_data_type = arrow::dictionary(arrow_index_data_type,
668                                            arrow_value_data_type,
669                                            ordered);
670   return GARROW_DICTIONARY_DATA_TYPE(garrow_data_type_new_raw(&arrow_data_type));
671 }
672 
673 /**
674  * garrow_dictionary_data_type_get_index_data_type:
675  * @dictionary_data_type: The #GArrowDictionaryDataType.
676  *
677  * Returns: (transfer full): The #GArrowDataType of index.
678  *
679  * Since: 0.8.0
680  */
681 GArrowDataType *
garrow_dictionary_data_type_get_index_data_type(GArrowDictionaryDataType * dictionary_data_type)682 garrow_dictionary_data_type_get_index_data_type(GArrowDictionaryDataType *dictionary_data_type)
683 {
684   auto arrow_data_type = garrow_data_type_get_raw(GARROW_DATA_TYPE(dictionary_data_type));
685   auto arrow_dictionary_data_type =
686     std::static_pointer_cast<arrow::DictionaryType>(arrow_data_type);
687   auto arrow_index_data_type = arrow_dictionary_data_type->index_type();
688   return garrow_data_type_new_raw(&arrow_index_data_type);
689 }
690 
691 /**
692  * garrow_dictionary_data_type_get_value_data_type:
693  * @dictionary_data_type: The #GArrowDictionaryDataType.
694  *
695  * Returns: (transfer full): The #GArrowDataType of dictionary values.
696  *
697  * Since: 0.14.0
698  */
699 GArrowDataType *
garrow_dictionary_data_type_get_value_data_type(GArrowDictionaryDataType * dictionary_data_type)700 garrow_dictionary_data_type_get_value_data_type(GArrowDictionaryDataType *dictionary_data_type)
701 {
702   auto arrow_data_type = garrow_data_type_get_raw(GARROW_DATA_TYPE(dictionary_data_type));
703   auto arrow_dictionary_data_type =
704     std::static_pointer_cast<arrow::DictionaryType>(arrow_data_type);
705   auto arrow_value_data_type = arrow_dictionary_data_type->value_type();
706   return garrow_data_type_new_raw(&arrow_value_data_type);
707 }
708 
709 /**
710  * garrow_dictionary_data_type_is_ordered:
711  * @dictionary_data_type: The #GArrowDictionaryDataType.
712  *
713  * Returns: Whether dictionary contents are ordered or not.
714  *
715  * Since: 0.8.0
716  */
717 gboolean
garrow_dictionary_data_type_is_ordered(GArrowDictionaryDataType * dictionary_data_type)718 garrow_dictionary_data_type_is_ordered(GArrowDictionaryDataType *dictionary_data_type)
719 {
720   auto arrow_data_type = garrow_data_type_get_raw(GARROW_DATA_TYPE(dictionary_data_type));
721   auto arrow_dictionary_data_type =
722     std::static_pointer_cast<arrow::DictionaryType>(arrow_data_type);
723   return arrow_dictionary_data_type->ordered();
724 }
725 
726 G_END_DECLS
727