This is an automated email from the ASF dual-hosted git repository.

kou pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/master by this push:
     new 9d2280f  ARROW-4915: [GLib][C++] Add arrow::NullBuilder support for 
GLib
9d2280f is described below

commit 9d2280fb9093580fc8073e972bbae3095b75203c
Author: Kenta Murata <[email protected]>
AuthorDate: Sun Mar 17 17:55:02 2019 +0900

    ARROW-4915: [GLib][C++] Add arrow::NullBuilder support for GLib
    
    This pull request add two things:
    
    1. `arrow::NullBuilder::AppendNulls()` function
    2. `GArrowNullArrayBuilder` class
    
    Author: Kenta Murata <[email protected]>
    Author: Kouhei Sutou <[email protected]>
    
    Closes #3938 from mrkn/glib_null_builder and squashes the following commits:
    
    e53b004e <Kouhei Sutou>  Accept NullArray.new(n)
    17c7c86c <Kenta Murata>  Add overflow check in NullBuilder::AppendNull()
    b31315a2 <Kenta Murata>  Add and fix version tags
    47af12da <Kenta Murata>  Rewrite with G_DECLARE_DERIVABLE_TYPE
    8ab32559 <Kenta Murata>  Put NullArrayBuilder tests in test-array-builder.rb
    1cdb500d <Kenta Murata>  Remove needless TODO comment
    6713a13c <Kenta Murata>  Check overflow in NullBuilder::AppendNulls()
    544fc6eb <Kenta Murata>  Add GArrowNullArrayBuilder
    2038ce23 <Kenta Murata>  Add NullBuilder::AppendNulls() function
---
 c_glib/arrow-glib/array-builder.cpp            | 81 ++++++++++++++++++++++++++
 c_glib/arrow-glib/array-builder.h              | 23 ++++++++
 c_glib/test/helper/buildable.rb                |  4 ++
 c_glib/test/test-array-builder.rb              | 33 +++++++++++
 cpp/src/arrow/array-test.cc                    |  5 +-
 cpp/src/arrow/array/builder_primitive.h        | 11 ++++
 ruby/red-arrow/lib/arrow/array-builder.rb      |  4 ++
 ruby/red-arrow/lib/arrow/array.rb              |  2 +-
 ruby/red-arrow/lib/arrow/loader.rb             |  1 +
 ruby/red-arrow/lib/arrow/null-array-builder.rb | 26 +++++++++
 10 files changed, 187 insertions(+), 3 deletions(-)

diff --git a/c_glib/arrow-glib/array-builder.cpp 
b/c_glib/arrow-glib/array-builder.cpp
index afdae8c..b9a9e71 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,81 @@ 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.
+ *
+ * Since: 0.13.0
+ */
+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.13.0
+ */
+gboolean
+garrow_null_array_builder_append_null(GArrowNullArrayBuilder *builder,
+                                      GError **error)
+{
+  return garrow_array_builder_append_null<arrow::NullBuilder *>
+    (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.13.0
+ */
+gboolean
+garrow_null_array_builder_append_nulls(GArrowNullArrayBuilder *builder,
+                                       gint64 n,
+                                       GError **error)
+{
+  return garrow_array_builder_append_nulls<arrow::NullBuilder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     n,
+     error,
+     "[null-array-builder][append-nulls]");
+}
+
+
 G_DEFINE_TYPE(GArrowBooleanArrayBuilder,
               garrow_boolean_array_builder,
               GARROW_TYPE_ARRAY_BUILDER)
@@ -3890,6 +3968,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 bc0a994..9fcadbd 100644
--- a/c_glib/arrow-glib/array-builder.h
+++ b/c_glib/arrow-glib/array-builder.h
@@ -45,6 +45,29 @@ GArrowArray        *garrow_array_builder_finish   
(GArrowArrayBuilder *builder,
                                                    GError **error);
 
 
+#define GARROW_TYPE_NULL_ARRAY_BUILDER (garrow_null_array_builder_get_type())
+G_DECLARE_DERIVABLE_TYPE(GArrowNullArrayBuilder,
+                         garrow_null_array_builder,
+                         GARROW,
+                         NULL_ARRAY_BUILDER,
+                         GArrowArrayBuilder)
+struct _GArrowNullArrayBuilderClass
+{
+  GArrowArrayBuilderClass parent_class;
+};
+
+GARROW_AVAILABLE_IN_0_13
+GArrowNullArrayBuilder *garrow_null_array_builder_new(void);
+
+GARROW_AVAILABLE_IN_0_13
+gboolean garrow_null_array_builder_append_null(GArrowNullArrayBuilder *builder,
+                                               GError **error);
+GARROW_AVAILABLE_IN_0_13
+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 a9c514c..788cffe 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-array-builder.rb 
b/c_glib/test/test-array-builder.rb
index f67cfec..d944422 100644
--- a/c_glib/test/test-array-builder.rb
+++ b/c_glib/test/test-array-builder.rb
@@ -113,6 +113,39 @@ class TestArrayBuilder < Test::Unit::TestCase
     super(create_builder, values)
   end
 
+  sub_test_case("NullArrayBuilder") do
+    def create_builder
+      Arrow::NullArrayBuilder.new
+    end
+
+    def value_data_type
+      Arrow::NullDataType.new
+    end
+
+    def builder_class_name
+      "null-array-builder"
+    end
+
+    def sample_values
+      [nil, nil, nil]
+    end
+
+    sub_test_case("value type") do
+      include ArrayBuilderValueTypeTests
+    end
+
+    test("#append_null") do
+      builder = create_builder
+      builder.append_null
+      assert_equal(build_array([nil]),
+                   builder.finish)
+    end
+
+    sub_test_case("#append_nulls") do
+      include ArrayBuilderAppendNullsTests
+    end
+  end
+
   sub_test_case("BooleanArrayBuilder") do
     def create_builder
       Arrow::BooleanArrayBuilder.new
diff --git a/cpp/src/arrow/array-test.cc b/cpp/src/arrow/array-test.cc
index 9451e00..b978682 100644
--- a/cpp/src/arrow/array-test.cc
+++ b/cpp/src/arrow/array-test.cc
@@ -259,11 +259,12 @@ TEST(TestNullBuilder, Basics) {
   ASSERT_OK(builder.AppendNull());
   ASSERT_OK(builder.Append(nullptr));
   ASSERT_OK(builder.AppendNull());
+  ASSERT_OK(builder.AppendNulls(2));
   ASSERT_OK(builder.Finish(&array));
 
   const auto& null_array = checked_cast<NullArray&>(*array);
-  ASSERT_EQ(null_array.length(), 3);
-  ASSERT_EQ(null_array.null_count(), 3);
+  ASSERT_EQ(null_array.length(), 5);
+  ASSERT_EQ(null_array.null_count(), 5);
 }
 
 // ----------------------------------------------------------------------
diff --git a/cpp/src/arrow/array/builder_primitive.h 
b/cpp/src/arrow/array/builder_primitive.h
index 95cfaa7..1025b4e 100644
--- a/cpp/src/arrow/array/builder_primitive.h
+++ b/cpp/src/arrow/array/builder_primitive.h
@@ -32,7 +32,18 @@ class ARROW_EXPORT NullBuilder : public ArrayBuilder {
   explicit NullBuilder(MemoryPool* pool ARROW_MEMORY_POOL_DEFAULT)
       : ArrayBuilder(null(), pool) {}
 
+  /// \brief Append the specified number of null elements
+  Status AppendNulls(int64_t length) {
+    auto new_length = length_ + length;
+    ARROW_RETURN_NOT_OK(CheckCapacity(new_length, length_));
+    null_count_ += length;
+    length_ = new_length;
+    return Status::OK();
+  }
+
+  /// \brief Append a single null element
   Status AppendNull() {
+    ARROW_RETURN_NOT_OK(CheckCapacity(length_ + 1, length_));
     ++null_count_;
     ++length_;
     return Status::OK();
diff --git a/ruby/red-arrow/lib/arrow/array-builder.rb 
b/ruby/red-arrow/lib/arrow/array-builder.rb
index 7cfc432..8083384 100644
--- a/ruby/red-arrow/lib/arrow/array-builder.rb
+++ b/ruby/red-arrow/lib/arrow/array-builder.rb
@@ -62,6 +62,10 @@ module Arrow
           Arrow::StringArray.new(values)
         end
       end
+
+      def buildable?(args)
+        args.size == method(:build).arity
+      end
     end
 
     def build(values)
diff --git a/ruby/red-arrow/lib/arrow/array.rb 
b/ruby/red-arrow/lib/arrow/array.rb
index f60025a..473bb86 100644
--- a/ruby/red-arrow/lib/arrow/array.rb
+++ b/ruby/red-arrow/lib/arrow/array.rb
@@ -24,7 +24,7 @@ module Arrow
         builder_class_name = "#{name}Builder"
         if const_defined?(builder_class_name)
           builder_class = const_get(builder_class_name)
-          if args.size == builder_class.method(:build).arity
+          if builder_class.buildable?(args)
             builder_class.build(*args)
           else
             super
diff --git a/ruby/red-arrow/lib/arrow/loader.rb 
b/ruby/red-arrow/lib/arrow/loader.rb
index a4b3604..5215a42 100644
--- a/ruby/red-arrow/lib/arrow/loader.rb
+++ b/ruby/red-arrow/lib/arrow/loader.rb
@@ -54,6 +54,7 @@ module Arrow
       require "arrow/file-output-stream"
       require "arrow/list-array-builder"
       require "arrow/list-data-type"
+      require "arrow/null-array-builder"
       require "arrow/path-extension"
       require "arrow/record"
       require "arrow/record-batch"
diff --git a/ruby/red-arrow/lib/arrow/null-array-builder.rb 
b/ruby/red-arrow/lib/arrow/null-array-builder.rb
new file mode 100644
index 0000000..01b7604
--- /dev/null
+++ b/ruby/red-arrow/lib/arrow/null-array-builder.rb
@@ -0,0 +1,26 @@
+# 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.
+
+module Arrow
+  class NullArrayBuilder
+    class << self
+      def buildable?(args)
+        super and args.collect(&:class) != [Integer]
+      end
+    end
+  end
+end

Reply via email to