Skip to content

Commit 730c87a

Browse files
committed
Add getters and setters for field_nullability and field_metadata
1 parent d0a3efc commit 730c87a

File tree

4 files changed

+193
-1
lines changed

4 files changed

+193
-1
lines changed

c_glib/arrow-glib/compute.cpp

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <arrow-glib/schema.hpp>
3535
#include <arrow-glib/table.hpp>
3636
#include <arrow-glib/type.hpp>
37+
#include <arrow-glib/internal-hash-table.hpp>
3738

3839
#include <arrow/acero/exec_plan.h>
3940
#include <arrow/acero/options.h>
@@ -7615,6 +7616,115 @@ garrow_make_struct_options_new(void)
76157616
return GARROW_MAKE_STRUCT_OPTIONS(options);
76167617
}
76177618

7619+
/**
7620+
* garrow_make_struct_options_set_field_nullability:
7621+
* @options: A #GArrowMakeStructOptions.
7622+
* @nullability: (element-type gboolean) (nullable) (transfer none): A #GList
7623+
* of nullability values, or %NULL.
7624+
*
7625+
* Sets the nullability information for each struct field.
7626+
*
7627+
* Since: 23.0.0
7628+
*/
7629+
void
7630+
garrow_make_struct_options_set_field_nullability(GArrowMakeStructOptions *options,
7631+
GList *nullability)
7632+
{
7633+
auto arrow_options = static_cast<arrow::compute::MakeStructOptions *>(
7634+
garrow_function_options_get_raw(GARROW_FUNCTION_OPTIONS(options)));
7635+
arrow_options->field_nullability.clear();
7636+
if (nullability) {
7637+
for (GList *node = nullability; node; node = node->next) {
7638+
gboolean value = GPOINTER_TO_INT(node->data);
7639+
arrow_options->field_nullability.push_back(value != FALSE);
7640+
}
7641+
}
7642+
}
7643+
7644+
/**
7645+
* garrow_make_struct_options_get_field_nullability:
7646+
* @options: A #GArrowMakeStructOptions.
7647+
*
7648+
* Returns: (element-type gboolean) (transfer full): A #GList of nullability
7649+
* values. It should be freed with g_list_free() when no longer needed.
7650+
*
7651+
* Gets the nullability information for each struct field.
7652+
*
7653+
* Since: 23.0.0
7654+
*/
7655+
GList *
7656+
garrow_make_struct_options_get_field_nullability(GArrowMakeStructOptions *options)
7657+
{
7658+
auto arrow_options = static_cast<arrow::compute::MakeStructOptions *>(
7659+
garrow_function_options_get_raw(GARROW_FUNCTION_OPTIONS(options)));
7660+
const auto &arrow_nullability = arrow_options->field_nullability;
7661+
GList *list = NULL;
7662+
for (gsize i = 0; i < arrow_nullability.size(); ++i) {
7663+
gboolean value = arrow_nullability[i] ? TRUE : FALSE;
7664+
list = g_list_prepend(list, GINT_TO_POINTER(value));
7665+
}
7666+
return g_list_reverse(list);
7667+
}
7668+
7669+
/**
7670+
* garrow_make_struct_options_set_field_metadata:
7671+
* @options: A #GArrowMakeStructOptions.
7672+
* @metadata: (element-type GHashTable) (nullable) (transfer none): A #GList of
7673+
* #GHashTable for each field's metadata, or %NULL.
7674+
*
7675+
* Sets the metadata for each struct field.
7676+
*
7677+
* Since: 23.0.0
7678+
*/
7679+
void
7680+
garrow_make_struct_options_set_field_metadata(GArrowMakeStructOptions *options,
7681+
GList *metadata)
7682+
{
7683+
auto arrow_options = static_cast<arrow::compute::MakeStructOptions *>(
7684+
garrow_function_options_get_raw(GARROW_FUNCTION_OPTIONS(options)));
7685+
arrow_options->field_metadata.clear();
7686+
if (metadata) {
7687+
for (GList *node = metadata; node; node = node->next) {
7688+
auto hash_table = static_cast<GHashTable *>(node->data);
7689+
if (hash_table) {
7690+
arrow_options->field_metadata.push_back(
7691+
garrow_internal_hash_table_to_metadata(hash_table));
7692+
} else {
7693+
arrow_options->field_metadata.push_back(NULLPTR);
7694+
}
7695+
}
7696+
}
7697+
}
7698+
7699+
/**
7700+
* garrow_make_struct_options_get_field_metadata:
7701+
* @options: A #GArrowMakeStructOptions.
7702+
*
7703+
* Returns: (element-type GHashTable) (transfer full): A #GList of #GHashTable
7704+
* for each field's metadata. It should be freed with g_list_free_full() and
7705+
* g_hash_table_unref() when no longer needed.
7706+
*
7707+
* Gets the metadata for each struct field.
7708+
*
7709+
* Since: 23.0.0
7710+
*/
7711+
GList *
7712+
garrow_make_struct_options_get_field_metadata(GArrowMakeStructOptions *options)
7713+
{
7714+
auto arrow_options = static_cast<arrow::compute::MakeStructOptions *>(
7715+
garrow_function_options_get_raw(GARROW_FUNCTION_OPTIONS(options)));
7716+
const auto &arrow_metadata = arrow_options->field_metadata;
7717+
GList *list = NULL;
7718+
for (gsize i = 0; i < arrow_metadata.size(); ++i) {
7719+
GHashTable *hash_table = NULL;
7720+
if (arrow_metadata[i] && arrow_metadata[i].get()) {
7721+
hash_table = garrow_internal_hash_table_from_metadata(arrow_metadata[i]);
7722+
}
7723+
list = g_list_prepend(list, hash_table);
7724+
}
7725+
return g_list_reverse(list);
7726+
}
7727+
76187728
G_END_DECLS
76197729

76207730
arrow::Result<arrow::FieldRef>

c_glib/arrow-glib/compute.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,4 +1354,22 @@ GARROW_AVAILABLE_IN_23_0
13541354
GArrowMakeStructOptions *
13551355
garrow_make_struct_options_new(void);
13561356

1357+
GARROW_AVAILABLE_IN_23_0
1358+
void
1359+
garrow_make_struct_options_set_field_nullability(GArrowMakeStructOptions *options,
1360+
GList *nullability);
1361+
1362+
GARROW_AVAILABLE_IN_23_0
1363+
GList *
1364+
garrow_make_struct_options_get_field_nullability(GArrowMakeStructOptions *options);
1365+
1366+
GARROW_AVAILABLE_IN_23_0
1367+
void
1368+
garrow_make_struct_options_set_field_metadata(GArrowMakeStructOptions *options,
1369+
GList *metadata);
1370+
1371+
GARROW_AVAILABLE_IN_23_0
1372+
GList *
1373+
garrow_make_struct_options_get_field_metadata(GArrowMakeStructOptions *options);
1374+
13571375
G_END_DECLS

c_glib/arrow-glib/internal-hash-table.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ garrow_internal_hash_table_to_metadata(GHashTable *metadata)
4040

4141
static inline GHashTable *
4242
garrow_internal_hash_table_from_metadata(
43-
const std::shared_ptr<arrow::KeyValueMetadata> &arrow_metadata)
43+
const std::shared_ptr<const arrow::KeyValueMetadata> &arrow_metadata)
4444
{
4545
auto metadata = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
4646
const auto &keys = arrow_metadata->keys();

c_glib/test/test-make-struct-options.rb

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,25 @@ def test_field_names_property
2828
assert_equal(["a", "b", "c"], @options.field_names)
2929
end
3030

31+
def test_field_nullability_property
32+
assert_equal([], @options.field_nullability)
33+
@options.field_names = ["a", "b", "c"]
34+
@options.field_nullability = [true, false, true]
35+
assert_equal([true, false, true], @options.field_nullability)
36+
end
37+
38+
def test_field_metadata_property
39+
assert_equal([], @options.field_metadata)
40+
@options.field_names = ["a", "b"]
41+
metadata1 = {"key1" => "value1", "key2" => "value2"}
42+
metadata2 = {"key3" => "value3"}
43+
@options.field_metadata = [metadata1, metadata2]
44+
result = @options.field_metadata
45+
assert_equal(2, result.size)
46+
assert_equal(metadata1, result[0])
47+
assert_equal(metadata2, result[1])
48+
end
49+
3150
def test_make_struct_function
3251
a = build_int8_array([1, 2, 3])
3352
b = build_boolean_array([true, false, nil])
@@ -52,4 +71,49 @@ def test_make_struct_function
5271
)
5372
assert_equal(expected, result)
5473
end
74+
75+
def test_make_struct_function_with_nullability
76+
a = build_int8_array([1, 2, 3])
77+
b = build_boolean_array([true, false, nil])
78+
args = [
79+
Arrow::ArrayDatum.new(a),
80+
Arrow::ArrayDatum.new(b),
81+
]
82+
@options.field_names = ["a", "b"]
83+
@options.field_nullability = [false, true]
84+
make_struct_function = Arrow::Function.find("make_struct")
85+
result = make_struct_function.execute(args, @options).value
86+
87+
expected = build_struct_array(
88+
[
89+
Arrow::Field.new("a", Arrow::Int8DataType.new, false),
90+
Arrow::Field.new("b", Arrow::BooleanDataType.new, true),
91+
],
92+
[
93+
{"a" => 1, "b" => true},
94+
{"a" => 2, "b" => false},
95+
{"a" => 3, "b" => nil},
96+
]
97+
)
98+
assert_equal(expected, result)
99+
end
100+
101+
def test_make_struct_function_with_metadata
102+
a = build_int8_array([1, 2, 3])
103+
b = build_boolean_array([true, false, nil])
104+
args = [
105+
Arrow::ArrayDatum.new(a),
106+
Arrow::ArrayDatum.new(b),
107+
]
108+
@options.field_names = ["a", "b"]
109+
metadata1 = {"key1" => "value1"}
110+
metadata2 = {"key2" => "value2"}
111+
@options.field_metadata = [metadata1, metadata2]
112+
make_struct_function = Arrow::Function.find("make_struct")
113+
result = make_struct_function.execute(args, @options).value
114+
115+
fields = result.value_data_type.fields
116+
assert_equal(metadata1, fields[0].metadata)
117+
assert_equal(metadata2, fields[1].metadata)
118+
end
55119
end

0 commit comments

Comments
 (0)