Skip to content

Commit 323eef7

Browse files
committed
Implement getter and setters for nullability and metadata in Ruby extension
1 parent 008f20c commit 323eef7

File tree

6 files changed

+348
-95
lines changed

6 files changed

+348
-95
lines changed

c_glib/arrow-glib/compute.cpp

Lines changed: 97 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8355,6 +8355,8 @@ garrow_pairwise_options_new(void)
83558355

83568356
enum {
83578357
PROP_MAKE_STRUCT_OPTIONS_FIELD_NAMES = 1,
8358+
PROP_MAKE_STRUCT_OPTIONS_FIELD_NULLABILITY,
8359+
PROP_MAKE_STRUCT_OPTIONS_FIELD_METADATA,
83588360
};
83598361

83608362
G_DEFINE_TYPE(GArrowMakeStructOptions,
@@ -8381,8 +8383,42 @@ garrow_make_struct_options_set_property(GObject *object,
83818383
}
83828384
}
83838385
// Keep nullability and metadata vectors in sync with names.
8384-
options->field_nullability.assign(options->field_names.size(), true);
8385-
options->field_metadata.assign(options->field_names.size(), NULLPTR);
8386+
const auto new_size = options->field_names.size();
8387+
if (options->field_nullability.size() != new_size) {
8388+
options->field_nullability.assign(new_size, true);
8389+
}
8390+
if (options->field_metadata.size() != new_size) {
8391+
options->field_metadata.assign(new_size, nullptr);
8392+
}
8393+
}
8394+
break;
8395+
case PROP_MAKE_STRUCT_OPTIONS_FIELD_NULLABILITY:
8396+
{
8397+
auto array = static_cast<GArray *>(g_value_get_boxed(value));
8398+
options->field_nullability.clear();
8399+
if (array) {
8400+
for (guint i = 0; i < array->len; ++i) {
8401+
auto nullability = g_array_index(array, gboolean, i);
8402+
options->field_nullability.push_back(nullability != FALSE);
8403+
}
8404+
}
8405+
}
8406+
break;
8407+
case PROP_MAKE_STRUCT_OPTIONS_FIELD_METADATA:
8408+
{
8409+
auto array = static_cast<GPtrArray *>(g_value_get_boxed(value));
8410+
options->field_metadata.clear();
8411+
if (array) {
8412+
for (guint i = 0; i < array->len; ++i) {
8413+
auto metadata = static_cast<GHashTable *>(g_ptr_array_index(array, i));
8414+
if (metadata) {
8415+
options->field_metadata.push_back(
8416+
garrow_internal_hash_table_to_metadata(metadata));
8417+
} else {
8418+
options->field_metadata.push_back(nullptr);
8419+
}
8420+
}
8421+
}
83868422
}
83878423
break;
83888424
default:
@@ -8411,6 +8447,31 @@ garrow_make_struct_options_get_property(GObject *object,
84118447
g_value_take_boxed(value, strv);
84128448
}
84138449
break;
8450+
case PROP_MAKE_STRUCT_OPTIONS_FIELD_NULLABILITY:
8451+
{
8452+
const auto &nullability = options->field_nullability;
8453+
auto array = g_array_sized_new(FALSE, FALSE, sizeof(gboolean), nullability.size());
8454+
for (gsize i = 0; i < nullability.size(); ++i) {
8455+
gboolean val = nullability[i] ? TRUE : FALSE;
8456+
g_array_append_val(array, val);
8457+
}
8458+
g_value_take_boxed(value, array);
8459+
}
8460+
break;
8461+
case PROP_MAKE_STRUCT_OPTIONS_FIELD_METADATA:
8462+
{
8463+
const auto &metadata = options->field_metadata;
8464+
auto array = g_ptr_array_sized_new(metadata.size());
8465+
for (gsize i = 0; i < metadata.size(); ++i) {
8466+
GHashTable *hash_table = nullptr;
8467+
if (metadata[i]) {
8468+
hash_table = garrow_internal_hash_table_from_metadata(metadata[i]);
8469+
}
8470+
g_ptr_array_add(array, hash_table);
8471+
}
8472+
g_value_take_boxed(value, array);
8473+
}
8474+
break;
84148475
default:
84158476
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
84168477
break;
@@ -8451,6 +8512,40 @@ garrow_make_struct_options_class_init(GArrowMakeStructOptionsClass *klass)
84518512
g_object_class_install_property(gobject_class,
84528513
PROP_MAKE_STRUCT_OPTIONS_FIELD_NAMES,
84538514
spec);
8515+
8516+
/**
8517+
* GArrowMakeStructOptions:field-nullability:
8518+
*
8519+
* Nullability for each field. This is a #GArray of #gboolean values.
8520+
*
8521+
* Since: 23.0.0
8522+
*/
8523+
spec = g_param_spec_boxed("field-nullability",
8524+
"Field nullability",
8525+
"Nullability for each field",
8526+
G_TYPE_ARRAY,
8527+
static_cast<GParamFlags>(G_PARAM_READWRITE));
8528+
g_object_class_install_property(gobject_class,
8529+
PROP_MAKE_STRUCT_OPTIONS_FIELD_NULLABILITY,
8530+
spec);
8531+
8532+
/**
8533+
* GArrowMakeStructOptions:field-metadata:
8534+
*
8535+
* Metadata for each field. This is a #GPtrArray of #GHashTable pointers
8536+
* (each hash table has utf8 keys and utf8 values), or %NULL for fields
8537+
* without metadata.
8538+
*
8539+
* Since: 23.0.0
8540+
*/
8541+
spec = g_param_spec_boxed("field-metadata",
8542+
"Field metadata",
8543+
"Metadata for each field",
8544+
G_TYPE_PTR_ARRAY,
8545+
static_cast<GParamFlags>(G_PARAM_READWRITE));
8546+
g_object_class_install_property(gobject_class,
8547+
PROP_MAKE_STRUCT_OPTIONS_FIELD_METADATA,
8548+
spec);
84548549
}
84558550

84568551
/**
@@ -8467,37 +8562,6 @@ garrow_make_struct_options_new(void)
84678562
return GARROW_MAKE_STRUCT_OPTIONS(options);
84688563
}
84698564

8470-
/**
8471-
* garrow_make_struct_options_add_field:
8472-
* @options: A #GArrowMakeStructOptions.
8473-
* @name: The name of the field to add.
8474-
* @nullability: Whether the field is nullable.
8475-
* @metadata: (nullable) (element-type utf8 utf8): A #GHashTable for the field's
8476-
* metadata, or %NULL.
8477-
*
8478-
* Adds a field to the struct options with the specified name, nullability,
8479-
* and optional metadata.
8480-
*
8481-
* Since: 23.0.0
8482-
*/
8483-
void
8484-
garrow_make_struct_options_add_field(GArrowMakeStructOptions *options,
8485-
const char *name,
8486-
gboolean nullability,
8487-
GHashTable *metadata)
8488-
{
8489-
auto arrow_options = static_cast<arrow::compute::MakeStructOptions *>(
8490-
garrow_function_options_get_raw(GARROW_FUNCTION_OPTIONS(options)));
8491-
arrow_options->field_names.emplace_back(name);
8492-
arrow_options->field_nullability.push_back(nullability != FALSE);
8493-
if (metadata) {
8494-
arrow_options->field_metadata.push_back(
8495-
garrow_internal_hash_table_to_metadata(metadata));
8496-
} else {
8497-
arrow_options->field_metadata.push_back(nullptr);
8498-
}
8499-
}
8500-
85018565
G_END_DECLS
85028566

85038567
arrow::Result<arrow::FieldRef>

c_glib/arrow-glib/compute.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,11 +1491,4 @@ GARROW_AVAILABLE_IN_23_0
14911491
GArrowMakeStructOptions *
14921492
garrow_make_struct_options_new(void);
14931493

1494-
GARROW_AVAILABLE_IN_23_0
1495-
void
1496-
garrow_make_struct_options_add_field(GArrowMakeStructOptions *options,
1497-
const char *name,
1498-
gboolean nullability,
1499-
GHashTable *metadata);
1500-
15011494
G_END_DECLS

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

Lines changed: 1 addition & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,14 @@ def test_field_names_property
2828
assert_equal(["a", "b", "c"], @options.field_names)
2929
end
3030

31-
def test_add_field
32-
@options.add_field("a", true, nil)
33-
@options.add_field("b", false, nil)
34-
metadata = {"key1" => "value1", "key2" => "value2"}
35-
@options.add_field("c", true, metadata)
36-
assert_equal(["a", "b", "c"], @options.field_names)
37-
end
38-
3931
def test_make_struct_function
4032
a = build_int8_array([1, 2, 3])
4133
b = build_boolean_array([true, false, nil])
4234
args = [
4335
Arrow::ArrayDatum.new(a),
4436
Arrow::ArrayDatum.new(b),
4537
]
46-
@options.add_field("a", true, nil)
47-
@options.add_field("b", true, nil)
38+
@options.field_names = ["a", "b"]
4839
make_struct_function = Arrow::Function.find("make_struct")
4940
result = make_struct_function.execute(args, @options).value
5041

@@ -61,49 +52,4 @@ def test_make_struct_function
6152
)
6253
assert_equal(expected, result)
6354
end
64-
65-
def test_make_struct_function_with_nullability
66-
a = build_int8_array([1, 2, 3])
67-
b = build_boolean_array([true, false, nil])
68-
args = [
69-
Arrow::ArrayDatum.new(a),
70-
Arrow::ArrayDatum.new(b),
71-
]
72-
@options.add_field("a", false, nil)
73-
@options.add_field("b", true, nil)
74-
make_struct_function = Arrow::Function.find("make_struct")
75-
result = make_struct_function.execute(args, @options).value
76-
77-
expected = build_struct_array(
78-
[
79-
Arrow::Field.new("a", Arrow::Int8DataType.new, false),
80-
Arrow::Field.new("b", Arrow::BooleanDataType.new, true),
81-
],
82-
[
83-
{"a" => 1, "b" => true},
84-
{"a" => 2, "b" => false},
85-
{"a" => 3, "b" => nil},
86-
]
87-
)
88-
assert_equal(expected, result)
89-
end
90-
91-
def test_make_struct_function_with_metadata
92-
a = build_int8_array([1, 2, 3])
93-
b = build_boolean_array([true, false, nil])
94-
args = [
95-
Arrow::ArrayDatum.new(a),
96-
Arrow::ArrayDatum.new(b),
97-
]
98-
metadata1 = {"key1" => "value1"}
99-
metadata2 = {"key2" => "value2"}
100-
@options.add_field("a", true, metadata1)
101-
@options.add_field("b", true, metadata2)
102-
make_struct_function = Arrow::Function.find("make_struct")
103-
result = make_struct_function.execute(args, @options).value
104-
105-
fields = result.value_data_type.fields
106-
assert_equal(metadata1, fields[0].metadata)
107-
assert_equal(metadata2, fields[1].metadata)
108-
end
10955
end

0 commit comments

Comments
 (0)