Skip to content

Commit

Permalink
ARROW-4915: [GLib][C++] Add arrow::NullBuilder support for GLib
Browse files Browse the repository at this point in the history
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:

e53b004 <Kouhei Sutou>  Accept NullArray.new(n)
17c7c86 <Kenta Murata>  Add overflow check in NullBuilder::AppendNull()
b31315a <Kenta Murata>  Add and fix version tags
47af12d <Kenta Murata>  Rewrite with G_DECLARE_DERIVABLE_TYPE
8ab3255 <Kenta Murata>  Put NullArrayBuilder tests in test-array-builder.rb
1cdb500 <Kenta Murata>  Remove needless TODO comment
6713a13 <Kenta Murata>  Check overflow in NullBuilder::AppendNulls()
544fc6e <Kenta Murata>  Add GArrowNullArrayBuilder
2038ce2 <Kenta Murata>  Add NullBuilder::AppendNulls() function
  • Loading branch information
mrkn authored and kou committed Mar 17, 2019
1 parent ad69ecb commit 9d2280f
Show file tree
Hide file tree
Showing 10 changed files with 187 additions and 3 deletions.
81 changes: 81 additions & 0 deletions c_glib/arrow-glib/array-builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
23 changes: 23 additions & 0 deletions c_glib/arrow-glib/array-builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down
4 changes: 4 additions & 0 deletions c_glib/test/helper/buildable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
33 changes: 33 additions & 0 deletions c_glib/test/test-array-builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,39 @@ def build_array(values)
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
Expand Down
5 changes: 3 additions & 2 deletions cpp/src/arrow/array-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

// ----------------------------------------------------------------------
Expand Down
11 changes: 11 additions & 0 deletions cpp/src/arrow/array/builder_primitive.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
4 changes: 4 additions & 0 deletions ruby/red-arrow/lib/arrow/array-builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ def build(values)
Arrow::StringArray.new(values)
end
end

def buildable?(args)
args.size == method(:build).arity
end
end

def build(values)
Expand Down
2 changes: 1 addition & 1 deletion ruby/red-arrow/lib/arrow/array.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def new(*args)
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
Expand Down
1 change: 1 addition & 0 deletions ruby/red-arrow/lib/arrow/loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def require_libraries
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"
Expand Down
26 changes: 26 additions & 0 deletions ruby/red-arrow/lib/arrow/null-array-builder.rb
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 9d2280f

Please sign in to comment.