diff --git a/c_glib/arrow-glib/array-builder.cpp b/c_glib/arrow-glib/array-builder.cpp index afdae8c8b3196..db2207c71d83d 100644 --- a/c_glib/arrow-glib/array-builder.cpp +++ b/c_glib/arrow-glib/array-builder.cpp @@ -153,6 +153,9 @@ G_BEGIN_DECLS * * You need to use array builder class to create a new array. * + * #GArrowNullArrayBuilder is the class to create a new + * #GArrowNullArray. + * * #GArrowBooleanArrayBuilder is the class to create a new * #GArrowBooleanArray. * @@ -409,6 +412,79 @@ garrow_array_builder_finish(GArrowArrayBuilder *builder, GError **error) } +G_DEFINE_TYPE(GArrowNullArrayBuilder, + garrow_null_array_builder, + GARROW_TYPE_ARRAY_BUILDER) + +static void +garrow_null_array_builder_init(GArrowNullArrayBuilder *builder) +{ +} + +static void +garrow_null_array_builder_class_init(GArrowNullArrayBuilderClass *klass) +{ +} + +/** + * garrow_null_array_builder_new: + * + * Returns: A newly created #GArrowNullArrayBuilder. + */ +GArrowNullArrayBuilder * +garrow_null_array_builder_new(void) +{ + auto builder = garrow_array_builder_new(arrow::null(), + NULL, + "[null-array-builder][new]"); + return GARROW_NULL_ARRAY_BUILDER(builder); +} + +/** + * garrow_null_array_builder_append_null: + * @builder: A #GArrowNullArrayBuilder. + * @error: (nullable): Return location for a #GError or %NULL. + * + * Returns: %TRUE on success, %FALSE if there was an error. + * + * Since: 0.14.0 + */ +gboolean +garrow_null_array_builder_append_null(GArrowNullArrayBuilder *builder, + GError **error) +{ + return garrow_array_builder_append_null + (GARROW_ARRAY_BUILDER(builder), + error, + "[null-array-builder][append-null]"); +} + +/** + * garrow_null_array_builder_append_nulls: + * @builder: A #GArrowNullArrayBuilder. + * @n: The number of null values to be appended. + * @error: (nullable): Return location for a #GError or %NULL. + * + * Append multiple nulls at once. It's more efficient than multiple + * `append_null()` calls. + * + * Returns: %TRUE on success, %FALSE if there was an error. + * + * Since: 0.14.0 + */ +gboolean +garrow_null_array_builder_append_nulls(GArrowNullArrayBuilder *builder, + gint64 n, + GError **error) +{ + return garrow_array_builder_append_nulls + (GARROW_ARRAY_BUILDER(builder), + n, + error, + "[boolean-array-builder][append-nulls]"); +} + + G_DEFINE_TYPE(GArrowBooleanArrayBuilder, garrow_boolean_array_builder, GARROW_TYPE_ARRAY_BUILDER) @@ -3890,6 +3966,9 @@ garrow_array_builder_new_raw(arrow::ArrayBuilder *arrow_builder, { if (type == G_TYPE_INVALID) { switch (arrow_builder->type()->id()) { + case arrow::Type::type::NA: + type = GARROW_TYPE_NULL_ARRAY_BUILDER; + break; case arrow::Type::type::BOOL: type = GARROW_TYPE_BOOLEAN_ARRAY_BUILDER; break; diff --git a/c_glib/arrow-glib/array-builder.h b/c_glib/arrow-glib/array-builder.h index bc0a99429b8f1..c80691c3750e6 100644 --- a/c_glib/arrow-glib/array-builder.h +++ b/c_glib/arrow-glib/array-builder.h @@ -45,6 +45,59 @@ GArrowArray *garrow_array_builder_finish (GArrowArrayBuilder *builder, GError **error); +#define GARROW_TYPE_NULL_ARRAY_BUILDER \ + (garrow_null_array_builder_get_type()) +#define GARROW_NULL_ARRAY_BUILDER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GARROW_TYPE_NULL_ARRAY_BUILDER, \ + GArrowNullArrayBuilder)) +#define GARROW_NULL_ARRAY_BUILDER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GARROW_TYPE_NULL_ARRAY_BUILDER, \ + GArrowNullArrayBuilderClass)) +#define GARROW_IS_NULL_ARRAY_BUILDER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), \ + GARROW_TYPE_NULL_ARRAY_BUILDER)) +#define GARROW_IS_NULL_ARRAY_BUILDER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), \ + GARROW_TYPE_NULL_ARRAY_BUILDER)) +#define GARROW_NULL_ARRAY_BUILDER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GARROW_TYPE_NULL_ARRAY_BUILDER, \ + GArrowNullArrayBuilderClass)) + +typedef struct _GArrowNullArrayBuilder GArrowNullArrayBuilder; +typedef struct _GArrowNullArrayBuilderClass GArrowNullArrayBuilderClass; + +/** + * GArrowNullArrayBuilder: + * + * It wraps `arrow::NullBuilder`. + */ +struct _GArrowNullArrayBuilder +{ + /*< private >*/ + GArrowArrayBuilder parent_instance; +}; + +struct _GArrowNullArrayBuilderClass +{ + GArrowArrayBuilderClass parent_class; +}; + +GType garrow_null_array_builder_get_type(void) G_GNUC_CONST; + +GArrowNullArrayBuilder *garrow_null_array_builder_new(void); + +/* TODO: should wrap AppendValue? */ + +gboolean garrow_null_array_builder_append_null(GArrowNullArrayBuilder *builder, + GError **error); +gboolean garrow_null_array_builder_append_nulls(GArrowNullArrayBuilder *builder, + gint64 n, + GError **error); + + #define GARROW_TYPE_BOOLEAN_ARRAY_BUILDER \ (garrow_boolean_array_builder_get_type()) #define GARROW_BOOLEAN_ARRAY_BUILDER(obj) \ diff --git a/c_glib/test/helper/buildable.rb b/c_glib/test/helper/buildable.rb index a9c514c27472f..788cffe6b90cd 100644 --- a/c_glib/test/helper/buildable.rb +++ b/c_glib/test/helper/buildable.rb @@ -17,6 +17,10 @@ module Helper module Buildable + def build_null_array(values) + build_array(Arrow::NullArrayBuilder.new, values) + end + def build_boolean_array(values) build_array(Arrow::BooleanArrayBuilder.new, values) end diff --git a/c_glib/test/test-null-array.rb b/c_glib/test/test-null-array.rb index 6aa8c037c17ee..eaafa9c1df615 100644 --- a/c_glib/test/test-null-array.rb +++ b/c_glib/test/test-null-array.rb @@ -16,18 +16,37 @@ # under the License. class TestNullArray < Test::Unit::TestCase + include Helper::Buildable + + def test_new + assert_equal(build_null_array([nil, nil, nil]), + Arrow::NullArray.new(3)) + end + def test_length - array = Arrow::NullArray.new(3) + builder = Arrow::NullArrayBuilder.new + builder.append_null + builder.append_null + builder.append_null + array = builder.finish assert_equal(3, array.length) end def test_n_nulls - array = Arrow::NullArray.new(3) + builder = Arrow::NullArrayBuilder.new + builder.append_null + builder.append_null + builder.append_null + array = builder.finish assert_equal(3, array.n_nulls) end def test_slice - array = Arrow::NullArray.new(3) + builder = Arrow::NullArrayBuilder.new + builder.append_null + builder.append_null + builder.append_null + array = builder.finish assert_equal(2, array.slice(1, 2).length) end end