You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by we...@apache.org on 2017/09/18 21:54:20 UTC

arrow git commit: ARROW-1548: [GLib] Support bulk append in builder

Repository: arrow
Updated Branches:
  refs/heads/master 63e7966ad -> 4a65fea01


ARROW-1548: [GLib] Support bulk append in builder

`append_values()` are for bulk values append.
`append_nulls()` are for bulk nulls append.

Author: Kouhei Sutou <ko...@clear-code.com>

Closes #1110 from kou/glib-support-bulk-append-in-builder and squashes the following commits:

49260319 [Kouhei Sutou] [GLib] Support bulk append in builder


Project: http://git-wip-us.apache.org/repos/asf/arrow/repo
Commit: http://git-wip-us.apache.org/repos/asf/arrow/commit/4a65fea0
Tree: http://git-wip-us.apache.org/repos/asf/arrow/tree/4a65fea0
Diff: http://git-wip-us.apache.org/repos/asf/arrow/diff/4a65fea0

Branch: refs/heads/master
Commit: 4a65fea011fe6e5f016a3170c778d53ab98356b3
Parents: 63e7966
Author: Kouhei Sutou <ko...@clear-code.com>
Authored: Mon Sep 18 17:54:15 2017 -0400
Committer: Wes McKinney <we...@twosigma.com>
Committed: Mon Sep 18 17:54:15 2017 -0400

----------------------------------------------------------------------
 c_glib/arrow-glib/array-builder.cpp       | 1147 +++++++++++++++++++++++-
 c_glib/arrow-glib/array-builder.h         |  153 ++++
 c_glib/doc/reference/arrow-glib-docs.sgml |    4 +
 c_glib/test/test-array-builder.rb         |  485 ++++++++++
 4 files changed, 1780 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/arrow/blob/4a65fea0/c_glib/arrow-glib/array-builder.cpp
----------------------------------------------------------------------
diff --git a/c_glib/arrow-glib/array-builder.cpp b/c_glib/arrow-glib/array-builder.cpp
index 126986d..a6fad87 100644
--- a/c_glib/arrow-glib/array-builder.cpp
+++ b/c_glib/arrow-glib/array-builder.cpp
@@ -38,6 +38,43 @@ garrow_array_builder_append(GArrowArrayBuilder *builder,
   return garrow_error_check(error, status, context);
 }
 
+template <typename BUILDER, typename VALUE>
+gboolean
+garrow_array_builder_append_values(GArrowArrayBuilder *builder,
+                                   const VALUE *values,
+                                   gint64 values_length,
+                                   const gboolean *is_valids,
+                                   gint64 is_valids_length,
+                                   GError **error,
+                                   const gchar *context)
+{
+  auto arrow_builder =
+    static_cast<BUILDER>(garrow_array_builder_get_raw(builder));
+  arrow::Status status;
+  if (is_valids_length > 0) {
+    if (values_length != is_valids_length) {
+      g_set_error(error,
+                  GARROW_ERROR,
+                  GARROW_ERROR_INVALID,
+                  "%s: values length and is_valids length must be equal: "
+                  "<%" G_GINT64_FORMAT "> != "
+                  "<%" G_GINT64_FORMAT ">",
+                  context,
+                  values_length,
+                  is_valids_length);
+      return FALSE;
+    }
+    uint8_t valid_bytes[is_valids_length];
+    for (gint64 i = 0; i < is_valids_length; ++i) {
+      valid_bytes[i] = is_valids[i];
+    }
+    status = arrow_builder->Append(values, values_length, valid_bytes);
+  } else {
+    status = arrow_builder->Append(values, values_length, nullptr);
+  }
+  return garrow_error_check(error, status, context);
+}
+
 template <typename BUILDER>
 gboolean
 garrow_array_builder_append_null(GArrowArrayBuilder *builder,
@@ -50,6 +87,35 @@ garrow_array_builder_append_null(GArrowArrayBuilder *builder,
   return garrow_error_check(error, status, context);
 }
 
+template <typename BUILDER>
+gboolean
+garrow_array_builder_append_nulls(GArrowArrayBuilder *builder,
+                                  gint64 n,
+                                  GError **error,
+                                  const gchar *context)
+{
+  if (n < 0) {
+    g_set_error(error,
+                GARROW_ERROR,
+                GARROW_ERROR_INVALID,
+                "%s: the number of nulls must be 0 or larger: "
+                "<%" G_GINT64_FORMAT ">",
+                context,
+                n);
+    return FALSE;
+  }
+  if (n == 0) {
+    return TRUE;
+  }
+
+  auto arrow_builder =
+    static_cast<BUILDER>(garrow_array_builder_get_raw(builder));
+  uint8_t valid_bytes[n];
+  memset(valid_bytes, 0, sizeof(uint8_t) * n);
+  auto status = arrow_builder->AppendNulls(valid_bytes, n);
+  return garrow_error_check(error, status, context);
+}
+
 G_BEGIN_DECLS
 
 /**
@@ -303,6 +369,47 @@ garrow_boolean_array_builder_append(GArrowBooleanArrayBuilder *builder,
 }
 
 /**
+ * garrow_boolean_array_builder_append_values:
+ * @builder: A #GArrowBooleanArrayBuilder.
+ * @values: (array length=values_length): The array of boolean.
+ * @values_length: The length of `values`.
+ * @is_valids: (nullable) (array length=is_valids_length): The array of
+ *   boolean that shows whether the Nth value is valid or not. If the
+ *   Nth `is_valids` is %TRUE, the Nth `values` is valid value. Otherwise
+ *   the Nth value is null value.
+ * @is_valids_length: The length of `is_valids`.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Append multiple values at once. It's efficient than multiple
+ * `append()` and `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_boolean_array_builder_append_values(GArrowBooleanArrayBuilder *builder,
+                                           const gboolean *values,
+                                           gint64 values_length,
+                                           const gboolean *is_valids,
+                                           gint64 is_valids_length,
+                                           GError **error)
+{
+  guint8 arrow_values[values_length];
+  for (gint64 i = 0; i < values_length; ++i) {
+    arrow_values[i] = values[i];
+  }
+  return garrow_array_builder_append_values<arrow::BooleanBuilder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     arrow_values,
+     values_length,
+     is_valids,
+     is_valids_length,
+     error,
+     "[boolean-array-builder][append-values]");
+}
+
+/**
  * garrow_boolean_array_builder_append_null:
  * @builder: A #GArrowBooleanArrayBuilder.
  * @error: (nullable): Return location for a #GError or %NULL.
@@ -319,6 +426,31 @@ garrow_boolean_array_builder_append_null(GArrowBooleanArrayBuilder *builder,
      "[boolean-array-builder][append-null]");
 }
 
+/**
+ * garrow_boolean_array_builder_append_nulls:
+ * @builder: A #GArrowBooleanArrayBuilder.
+ * @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 efficient than multiple
+ * `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_boolean_array_builder_append_nulls(GArrowBooleanArrayBuilder *builder,
+                                          gint64 n,
+                                          GError **error)
+{
+  return garrow_array_builder_append_nulls<arrow::BooleanBuilder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     n,
+     error,
+     "[boolean-array-builder][append-nulls]");
+}
+
 
 G_DEFINE_TYPE(GArrowIntArrayBuilder,
               garrow_int_array_builder,
@@ -374,6 +506,43 @@ garrow_int_array_builder_append(GArrowIntArrayBuilder *builder,
 }
 
 /**
+ * garrow_int_array_builder_append_values:
+ * @builder: A #GArrowIntArrayBuilder.
+ * @values: (array length=values_length): The array of int.
+ * @values_length: The length of `values`.
+ * @is_valids: (nullable) (array length=is_valids_length): The array of
+ *   boolean that shows whether the Nth value is valid or not. If the
+ *   Nth `is_valids` is %TRUE, the Nth `values` is valid value. Otherwise
+ *   the Nth value is null value.
+ * @is_valids_length: The length of `is_valids`.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Append multiple values at once. It's efficient than multiple
+ * `append()` and `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_int_array_builder_append_values(GArrowIntArrayBuilder *builder,
+                                       const gint64 *values,
+                                       gint64 values_length,
+                                       const gboolean *is_valids,
+                                       gint64 is_valids_length,
+                                       GError **error)
+{
+  return garrow_array_builder_append_values<arrow::AdaptiveIntBuilder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     reinterpret_cast<const int64_t *>(values),
+     values_length,
+     is_valids,
+     is_valids_length,
+     error,
+     "[int-array-builder][append-values]");
+}
+
+/**
  * garrow_int_array_builder_append_null:
  * @builder: A #GArrowIntArrayBuilder.
  * @error: (nullable): Return location for a #GError or %NULL.
@@ -392,6 +561,31 @@ garrow_int_array_builder_append_null(GArrowIntArrayBuilder *builder,
      "[int-array-builder][append-null]");
 }
 
+/**
+ * garrow_int_array_builder_append_nulls:
+ * @builder: A #GArrowIntArrayBuilder.
+ * @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 efficient than multiple
+ * `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_int_array_builder_append_nulls(GArrowIntArrayBuilder *builder,
+                                      gint64 n,
+                                      GError **error)
+{
+  return garrow_array_builder_append_nulls<arrow::AdaptiveIntBuilder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     n,
+     error,
+     "[int-array-builder][append-nulls]");
+}
+
 
 G_DEFINE_TYPE(GArrowInt8ArrayBuilder,
               garrow_int8_array_builder,
@@ -442,6 +636,43 @@ garrow_int8_array_builder_append(GArrowInt8ArrayBuilder *builder,
 }
 
 /**
+ * garrow_int8_array_builder_append_values:
+ * @builder: A #GArrowInt8ArrayBuilder.
+ * @values: (array length=values_length): The array of int8.
+ * @values_length: The length of `values`.
+ * @is_valids: (nullable) (array length=is_valids_length): The array of
+ *   boolean that shows whether the Nth value is valid or not. If the
+ *   Nth `is_valids` is %TRUE, the Nth `values` is valid value. Otherwise
+ *   the Nth value is null value.
+ * @is_valids_length: The length of `is_valids`.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Append multiple values at once. It's efficient than multiple
+ * `append()` and `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_int8_array_builder_append_values(GArrowInt8ArrayBuilder *builder,
+                                        const gint8 *values,
+                                        gint64 values_length,
+                                        const gboolean *is_valids,
+                                        gint64 is_valids_length,
+                                        GError **error)
+{
+  return garrow_array_builder_append_values<arrow::Int8Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     values,
+     values_length,
+     is_valids,
+     is_valids_length,
+     error,
+     "[int8-array-builder][append-values]");
+}
+
+/**
  * garrow_int8_array_builder_append_null:
  * @builder: A #GArrowInt8ArrayBuilder.
  * @error: (nullable): Return location for a #GError or %NULL.
@@ -458,6 +689,31 @@ garrow_int8_array_builder_append_null(GArrowInt8ArrayBuilder *builder,
      "[int8-array-builder][append-null]");
 }
 
+/**
+ * garrow_int8_array_builder_append_nulls:
+ * @builder: A #GArrowInt8ArrayBuilder.
+ * @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 efficient than multiple
+ * `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_int8_array_builder_append_nulls(GArrowInt8ArrayBuilder *builder,
+                                       gint64 n,
+                                       GError **error)
+{
+  return garrow_array_builder_append_nulls<arrow::Int8Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     n,
+     error,
+     "[int8-array-builder][append-nulls]");
+}
+
 
 G_DEFINE_TYPE(GArrowUInt8ArrayBuilder,
               garrow_uint8_array_builder,
@@ -508,6 +764,43 @@ garrow_uint8_array_builder_append(GArrowUInt8ArrayBuilder *builder,
 }
 
 /**
+ * garrow_uint8_array_builder_append_values:
+ * @builder: A #GArrowUInt8ArrayBuilder.
+ * @values: (array length=values_length): The array of uint8.
+ * @values_length: The length of `values`.
+ * @is_valids: (nullable) (array length=is_valids_length): The array of
+ *   boolean that shows whether the Nth value is valid or not. If the
+ *   Nth `is_valids` is %TRUE, the Nth `values` is valid value. Otherwise
+ *   the Nth value is null value.
+ * @is_valids_length: The length of `is_valids`.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Append multiple values at once. It's efficient than multiple
+ * `append()` and `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_uint8_array_builder_append_values(GArrowUInt8ArrayBuilder *builder,
+                                         const guint8 *values,
+                                         gint64 values_length,
+                                         const gboolean *is_valids,
+                                         gint64 is_valids_length,
+                                         GError **error)
+{
+  return garrow_array_builder_append_values<arrow::UInt8Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     values,
+     values_length,
+     is_valids,
+     is_valids_length,
+     error,
+     "[uint8-array-builder][append-values]");
+}
+
+/**
  * garrow_uint8_array_builder_append_null:
  * @builder: A #GArrowUInt8ArrayBuilder.
  * @error: (nullable): Return location for a #GError or %NULL.
@@ -524,6 +817,31 @@ garrow_uint8_array_builder_append_null(GArrowUInt8ArrayBuilder *builder,
      "[uint8-array-builder][append-null]");
 }
 
+/**
+ * garrow_uint8_array_builder_append_nulls:
+ * @builder: A #GArrowUInt8ArrayBuilder.
+ * @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 efficient than multiple
+ * `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_uint8_array_builder_append_nulls(GArrowUInt8ArrayBuilder *builder,
+                                        gint64 n,
+                                        GError **error)
+{
+  return garrow_array_builder_append_nulls<arrow::UInt8Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     n,
+     error,
+     "[uint8-array-builder][append-nulls]");
+}
+
 
 G_DEFINE_TYPE(GArrowInt16ArrayBuilder,
               garrow_int16_array_builder,
@@ -574,6 +892,43 @@ garrow_int16_array_builder_append(GArrowInt16ArrayBuilder *builder,
 }
 
 /**
+ * garrow_int16_array_builder_append_values:
+ * @builder: A #GArrowInt16ArrayBuilder.
+ * @values: (array length=values_length): The array of int16.
+ * @values_length: The length of `values`.
+ * @is_valids: (nullable) (array length=is_valids_length): The array of
+ *   boolean that shows whether the Nth value is valid or not. If the
+ *   Nth `is_valids` is %TRUE, the Nth `values` is valid value. Otherwise
+ *   the Nth value is null value.
+ * @is_valids_length: The length of `is_valids`.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Append multiple values at once. It's efficient than multiple
+ * `append()` and `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_int16_array_builder_append_values(GArrowInt16ArrayBuilder *builder,
+                                         const gint16 *values,
+                                         gint64 values_length,
+                                         const gboolean *is_valids,
+                                         gint64 is_valids_length,
+                                         GError **error)
+{
+  return garrow_array_builder_append_values<arrow::Int16Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     values,
+     values_length,
+     is_valids,
+     is_valids_length,
+     error,
+     "[int16-array-builder][append-values]");
+}
+
+/**
  * garrow_int16_array_builder_append_null:
  * @builder: A #GArrowInt16ArrayBuilder.
  * @error: (nullable): Return location for a #GError or %NULL.
@@ -590,6 +945,31 @@ garrow_int16_array_builder_append_null(GArrowInt16ArrayBuilder *builder,
      "[int16-array-builder][append-null]");
 }
 
+/**
+ * garrow_int16_array_builder_append_nulls:
+ * @builder: A #GArrowInt16ArrayBuilder.
+ * @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 efficient than multiple
+ * `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_int16_array_builder_append_nulls(GArrowInt16ArrayBuilder *builder,
+                                        gint64 n,
+                                        GError **error)
+{
+  return garrow_array_builder_append_nulls<arrow::Int16Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     n,
+     error,
+     "[int16-array-builder][append-nulls]");
+}
+
 
 G_DEFINE_TYPE(GArrowUInt16ArrayBuilder,
               garrow_uint16_array_builder,
@@ -640,6 +1020,43 @@ garrow_uint16_array_builder_append(GArrowUInt16ArrayBuilder *builder,
 }
 
 /**
+ * garrow_uint16_array_builder_append_values:
+ * @builder: A #GArrowUInt16ArrayBuilder.
+ * @values: (array length=values_length): The array of uint16.
+ * @values_length: The length of `values`.
+ * @is_valids: (nullable) (array length=is_valids_length): The array of
+ *   boolean that shows whether the Nth value is valid or not. If the
+ *   Nth `is_valids` is %TRUE, the Nth `values` is valid value. Otherwise
+ *   the Nth value is null value.
+ * @is_valids_length: The length of `is_valids`.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Append multiple values at once. It's efficient than multiple
+ * `append()` and `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_uint16_array_builder_append_values(GArrowUInt16ArrayBuilder *builder,
+                                          const guint16 *values,
+                                          gint64 values_length,
+                                          const gboolean *is_valids,
+                                          gint64 is_valids_length,
+                                          GError **error)
+{
+  return garrow_array_builder_append_values<arrow::UInt16Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     values,
+     values_length,
+     is_valids,
+     is_valids_length,
+     error,
+     "[uint16-array-builder][append-values]");
+}
+
+/**
  * garrow_uint16_array_builder_append_null:
  * @builder: A #GArrowUInt16ArrayBuilder.
  * @error: (nullable): Return location for a #GError or %NULL.
@@ -656,6 +1073,31 @@ garrow_uint16_array_builder_append_null(GArrowUInt16ArrayBuilder *builder,
      "[uint16-array-builder][append-null]");
 }
 
+/**
+ * garrow_uint16_array_builder_append_nulls:
+ * @builder: A #GArrowUInt16ArrayBuilder.
+ * @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 efficient than multiple
+ * `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_uint16_array_builder_append_nulls(GArrowUInt16ArrayBuilder *builder,
+                                         gint64 n,
+                                         GError **error)
+{
+  return garrow_array_builder_append_nulls<arrow::UInt16Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     n,
+     error,
+     "[uint16-array-builder][append-nulls]");
+}
+
 
 G_DEFINE_TYPE(GArrowInt32ArrayBuilder,
               garrow_int32_array_builder,
@@ -706,6 +1148,43 @@ garrow_int32_array_builder_append(GArrowInt32ArrayBuilder *builder,
 }
 
 /**
+ * garrow_int32_array_builder_append_values:
+ * @builder: A #GArrowInt32ArrayBuilder.
+ * @values: (array length=values_length): The array of int32.
+ * @values_length: The length of `values`.
+ * @is_valids: (nullable) (array length=is_valids_length): The array of
+ *   boolean that shows whether the Nth value is valid or not. If the
+ *   Nth `is_valids` is %TRUE, the Nth `values` is valid value. Otherwise
+ *   the Nth value is null value.
+ * @is_valids_length: The length of `is_valids`.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Append multiple values at once. It's efficient than multiple
+ * `append()` and `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_int32_array_builder_append_values(GArrowInt32ArrayBuilder *builder,
+                                         const gint32 *values,
+                                         gint64 values_length,
+                                         const gboolean *is_valids,
+                                         gint64 is_valids_length,
+                                         GError **error)
+{
+  return garrow_array_builder_append_values<arrow::Int32Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     values,
+     values_length,
+     is_valids,
+     is_valids_length,
+     error,
+     "[int32-array-builder][append-values]");
+}
+
+/**
  * garrow_int32_array_builder_append_null:
  * @builder: A #GArrowInt32ArrayBuilder.
  * @error: (nullable): Return location for a #GError or %NULL.
@@ -714,7 +1193,7 @@ garrow_int32_array_builder_append(GArrowInt32ArrayBuilder *builder,
  */
 gboolean
 garrow_int32_array_builder_append_null(GArrowInt32ArrayBuilder *builder,
-                                      GError **error)
+                                       GError **error)
 {
   return garrow_array_builder_append_null<arrow::Int32Builder *>
     (GARROW_ARRAY_BUILDER(builder),
@@ -722,6 +1201,31 @@ garrow_int32_array_builder_append_null(GArrowInt32ArrayBuilder *builder,
      "[int32-array-builder][append-null]");
 }
 
+/**
+ * garrow_int32_array_builder_append_nulls:
+ * @builder: A #GArrowInt32ArrayBuilder.
+ * @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 efficient than multiple
+ * `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_int32_array_builder_append_nulls(GArrowInt32ArrayBuilder *builder,
+                                        gint64 n,
+                                        GError **error)
+{
+  return garrow_array_builder_append_nulls<arrow::Int32Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     n,
+     error,
+     "[int32-array-builder][append-nulls]");
+}
+
 
 G_DEFINE_TYPE(GArrowUInt32ArrayBuilder,
               garrow_uint32_array_builder,
@@ -772,6 +1276,43 @@ garrow_uint32_array_builder_append(GArrowUInt32ArrayBuilder *builder,
 }
 
 /**
+ * garrow_uint32_array_builder_append_values:
+ * @builder: A #GArrowUInt32ArrayBuilder.
+ * @values: (array length=values_length): The array of uint32.
+ * @values_length: The length of `values`.
+ * @is_valids: (nullable) (array length=is_valids_length): The array of
+ *   boolean that shows whether the Nth value is valid or not. If the
+ *   Nth `is_valids` is %TRUE, the Nth `values` is valid value. Otherwise
+ *   the Nth value is null value.
+ * @is_valids_length: The length of `is_valids`.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Append multiple values at once. It's efficient than multiple
+ * `append()` and `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_uint32_array_builder_append_values(GArrowUInt32ArrayBuilder *builder,
+                                          const guint32 *values,
+                                          gint64 values_length,
+                                          const gboolean *is_valids,
+                                          gint64 is_valids_length,
+                                          GError **error)
+{
+  return garrow_array_builder_append_values<arrow::UInt32Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     values,
+     values_length,
+     is_valids,
+     is_valids_length,
+     error,
+     "[uint32-array-builder][append-values]");
+}
+
+/**
  * garrow_uint32_array_builder_append_null:
  * @builder: A #GArrowUInt32ArrayBuilder.
  * @error: (nullable): Return location for a #GError or %NULL.
@@ -788,13 +1329,38 @@ garrow_uint32_array_builder_append_null(GArrowUInt32ArrayBuilder *builder,
      "[uint32-array-builder][append-null]");
 }
 
-
-G_DEFINE_TYPE(GArrowInt64ArrayBuilder,
-              garrow_int64_array_builder,
-              GARROW_TYPE_ARRAY_BUILDER)
-
-static void
-garrow_int64_array_builder_init(GArrowInt64ArrayBuilder *builder)
+/**
+ * garrow_uint32_array_builder_append_nulls:
+ * @builder: A #GArrowUInt32ArrayBuilder.
+ * @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 efficient than multiple
+ * `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_uint32_array_builder_append_nulls(GArrowUInt32ArrayBuilder *builder,
+                                         gint64 n,
+                                         GError **error)
+{
+  return garrow_array_builder_append_nulls<arrow::UInt32Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     n,
+     error,
+     "[uint32-array-builder][append-nulls]");
+}
+
+
+G_DEFINE_TYPE(GArrowInt64ArrayBuilder,
+              garrow_int64_array_builder,
+              GARROW_TYPE_ARRAY_BUILDER)
+
+static void
+garrow_int64_array_builder_init(GArrowInt64ArrayBuilder *builder)
 {
 }
 
@@ -838,6 +1404,43 @@ garrow_int64_array_builder_append(GArrowInt64ArrayBuilder *builder,
 }
 
 /**
+ * garrow_int64_array_builder_append_values:
+ * @builder: A #GArrowInt64ArrayBuilder.
+ * @values: (array length=values_length): The array of int64.
+ * @values_length: The length of `values`.
+ * @is_valids: (nullable) (array length=is_valids_length): The array of
+ *   boolean that shows whether the Nth value is valid or not. If the
+ *   Nth `is_valids` is %TRUE, the Nth `values` is valid value. Otherwise
+ *   the Nth value is null value.
+ * @is_valids_length: The length of `is_valids`.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Append multiple values at once. It's efficient than multiple
+ * `append()` and `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_int64_array_builder_append_values(GArrowInt64ArrayBuilder *builder,
+                                         const gint64 *values,
+                                         gint64 values_length,
+                                         const gboolean *is_valids,
+                                         gint64 is_valids_length,
+                                         GError **error)
+{
+  return garrow_array_builder_append_values<arrow::Int64Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     reinterpret_cast<const int64_t *>(values),
+     values_length,
+     is_valids,
+     is_valids_length,
+     error,
+     "[int64-array-builder][append-values]");
+}
+
+/**
  * garrow_int64_array_builder_append_null:
  * @builder: A #GArrowInt64ArrayBuilder.
  * @error: (nullable): Return location for a #GError or %NULL.
@@ -854,6 +1457,31 @@ garrow_int64_array_builder_append_null(GArrowInt64ArrayBuilder *builder,
      "[int64-array-builder][append-null]");
 }
 
+/**
+ * garrow_int64_array_builder_append_nulls:
+ * @builder: A #GArrowInt64ArrayBuilder.
+ * @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 efficient than multiple
+ * `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_int64_array_builder_append_nulls(GArrowInt64ArrayBuilder *builder,
+                                        gint64 n,
+                                        GError **error)
+{
+  return garrow_array_builder_append_nulls<arrow::Int64Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     n,
+     error,
+     "[int64-array-builder][append-nulls]");
+}
+
 
 G_DEFINE_TYPE(GArrowUInt64ArrayBuilder,
               garrow_uint64_array_builder,
@@ -904,6 +1532,43 @@ garrow_uint64_array_builder_append(GArrowUInt64ArrayBuilder *builder,
 }
 
 /**
+ * garrow_uint64_array_builder_append_values:
+ * @builder: A #GArrowUInt64ArrayBuilder.
+ * @values: (array length=values_length): The array of uint64.
+ * @values_length: The length of `values`.
+ * @is_valids: (nullable) (array length=is_valids_length): The array of
+ *   boolean that shows whether the Nth value is valid or not. If the
+ *   Nth `is_valids` is %TRUE, the Nth `values` is valid value. Otherwise
+ *   the Nth value is null value.
+ * @is_valids_length: The length of `is_valids`.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Append multiple values at once. It's efficient than multiple
+ * `append()` and `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_uint64_array_builder_append_values(GArrowUInt64ArrayBuilder *builder,
+                                          const guint64 *values,
+                                          gint64 values_length,
+                                          const gboolean *is_valids,
+                                          gint64 is_valids_length,
+                                          GError **error)
+{
+  return garrow_array_builder_append_values<arrow::UInt64Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     reinterpret_cast<const uint64_t *>(values),
+     values_length,
+     is_valids,
+     is_valids_length,
+     error,
+     "[uint64-array-builder][append-values]");
+}
+
+/**
  * garrow_uint64_array_builder_append_null:
  * @builder: A #GArrowUInt64ArrayBuilder.
  * @error: (nullable): Return location for a #GError or %NULL.
@@ -912,7 +1577,7 @@ garrow_uint64_array_builder_append(GArrowUInt64ArrayBuilder *builder,
  */
 gboolean
 garrow_uint64_array_builder_append_null(GArrowUInt64ArrayBuilder *builder,
-                                       GError **error)
+                                        GError **error)
 {
   return garrow_array_builder_append_null<arrow::UInt64Builder *>
     (GARROW_ARRAY_BUILDER(builder),
@@ -920,6 +1585,31 @@ garrow_uint64_array_builder_append_null(GArrowUInt64ArrayBuilder *builder,
      "[uint64-array-builder][append-null]");
 }
 
+/**
+ * garrow_uint64_array_builder_append_nulls:
+ * @builder: A #GArrowUInt64ArrayBuilder.
+ * @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 efficient than multiple
+ * `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_uint64_array_builder_append_nulls(GArrowUInt64ArrayBuilder *builder,
+                                         gint64 n,
+                                         GError **error)
+{
+  return garrow_array_builder_append_nulls<arrow::UInt64Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     n,
+     error,
+     "[uint64-array-builder][append-nulls]");
+}
+
 
 G_DEFINE_TYPE(GArrowFloatArrayBuilder,
               garrow_float_array_builder,
@@ -970,6 +1660,43 @@ garrow_float_array_builder_append(GArrowFloatArrayBuilder *builder,
 }
 
 /**
+ * garrow_float_array_builder_append_values:
+ * @builder: A #GArrowFloatArrayBuilder.
+ * @values: (array length=values_length): The array of float.
+ * @values_length: The length of `values`.
+ * @is_valids: (nullable) (array length=is_valids_length): The array of
+ *   boolean that shows whether the Nth value is valid or not. If the
+ *   Nth `is_valids` is %TRUE, the Nth `values` is valid value. Otherwise
+ *   the Nth value is null value.
+ * @is_valids_length: The length of `is_valids`.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Append multiple values at once. It's efficient than multiple
+ * `append()` and `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_float_array_builder_append_values(GArrowFloatArrayBuilder *builder,
+                                         const gfloat *values,
+                                         gint64 values_length,
+                                         const gboolean *is_valids,
+                                         gint64 is_valids_length,
+                                         GError **error)
+{
+  return garrow_array_builder_append_values<arrow::FloatBuilder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     values,
+     values_length,
+     is_valids,
+     is_valids_length,
+     error,
+     "[float-array-builder][append-values]");
+}
+
+/**
  * garrow_float_array_builder_append_null:
  * @builder: A #GArrowFloatArrayBuilder.
  * @error: (nullable): Return location for a #GError or %NULL.
@@ -986,6 +1713,31 @@ garrow_float_array_builder_append_null(GArrowFloatArrayBuilder *builder,
      "[float-array-builder][append-null]");
 }
 
+/**
+ * garrow_float_array_builder_append_nulls:
+ * @builder: A #GArrowFloatArrayBuilder.
+ * @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 efficient than multiple
+ * `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_float_array_builder_append_nulls(GArrowFloatArrayBuilder *builder,
+                                        gint64 n,
+                                        GError **error)
+{
+  return garrow_array_builder_append_nulls<arrow::FloatBuilder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     n,
+     error,
+     "[float-array-builder][append-nulls]");
+}
+
 
 G_DEFINE_TYPE(GArrowDoubleArrayBuilder,
               garrow_double_array_builder,
@@ -1036,6 +1788,43 @@ garrow_double_array_builder_append(GArrowDoubleArrayBuilder *builder,
 }
 
 /**
+ * garrow_double_array_builder_append_values:
+ * @builder: A #GArrowDoubleArrayBuilder.
+ * @values: (array length=values_length): The array of double.
+ * @values_length: The length of `values`.
+ * @is_valids: (nullable) (array length=is_valids_length): The array of
+ *   boolean that shows whether the Nth value is valid or not. If the
+ *   Nth `is_valids` is %TRUE, the Nth `values` is valid value. Otherwise
+ *   the Nth value is null value.
+ * @is_valids_length: The length of `is_valids`.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Append multiple values at once. It's efficient than multiple
+ * `append()` and `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_double_array_builder_append_values(GArrowDoubleArrayBuilder *builder,
+                                          const gdouble *values,
+                                          gint64 values_length,
+                                          const gboolean *is_valids,
+                                          gint64 is_valids_length,
+                                          GError **error)
+{
+  return garrow_array_builder_append_values<arrow::DoubleBuilder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     values,
+     values_length,
+     is_valids,
+     is_valids_length,
+     error,
+     "[double-array-builder][append-values]");
+}
+
+/**
  * garrow_double_array_builder_append_null:
  * @builder: A #GArrowDoubleArrayBuilder.
  * @error: (nullable): Return location for a #GError or %NULL.
@@ -1052,6 +1841,31 @@ garrow_double_array_builder_append_null(GArrowDoubleArrayBuilder *builder,
      "[double-array-builder][append-null]");
 }
 
+/**
+ * garrow_double_array_builder_append_nulls:
+ * @builder: A #GArrowDoubleArrayBuilder.
+ * @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 efficient than multiple
+ * `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_double_array_builder_append_nulls(GArrowDoubleArrayBuilder *builder,
+                                         gint64 n,
+                                         GError **error)
+{
+  return garrow_array_builder_append_nulls<arrow::DoubleBuilder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     n,
+     error,
+     "[double-array-builder][append-nulls]");
+}
+
 
 G_DEFINE_TYPE(GArrowBinaryArrayBuilder,
               garrow_binary_array_builder,
@@ -1226,6 +2040,44 @@ garrow_date32_array_builder_append(GArrowDate32ArrayBuilder *builder,
 }
 
 /**
+ * garrow_date32_array_builder_append_values:
+ * @builder: A #GArrowDate32ArrayBuilder.
+ * @values: (array length=values_length): The array of
+ *   the number of days since UNIX epoch in signed 32bit integer.
+ * @values_length: The length of `values`.
+ * @is_valids: (nullable) (array length=is_valids_length): The array of
+ *   boolean that shows whether the Nth value is valid or not. If the
+ *   Nth `is_valids` is %TRUE, the Nth `values` is valid value. Otherwise
+ *   the Nth value is null value.
+ * @is_valids_length: The length of `is_valids`.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Append multiple values at once. It's efficient than multiple
+ * `append()` and `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_date32_array_builder_append_values(GArrowDate32ArrayBuilder *builder,
+                                          const gint32 *values,
+                                          gint64 values_length,
+                                          const gboolean *is_valids,
+                                          gint64 is_valids_length,
+                                          GError **error)
+{
+  return garrow_array_builder_append_values<arrow::Date32Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     values,
+     values_length,
+     is_valids,
+     is_valids_length,
+     error,
+     "[date32-array-builder][append-values]");
+}
+
+/**
  * garrow_date32_array_builder_append_null:
  * @builder: A #GArrowDate32ArrayBuilder.
  * @error: (nullable): Return location for a #GError or %NULL.
@@ -1244,6 +2096,31 @@ garrow_date32_array_builder_append_null(GArrowDate32ArrayBuilder *builder,
      "[date32-array-builder][append-null]");
 }
 
+/**
+ * garrow_date32_array_builder_append_nulls:
+ * @builder: A #GArrowDate32ArrayBuilder.
+ * @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 efficient than multiple
+ * `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_date32_array_builder_append_nulls(GArrowDate32ArrayBuilder *builder,
+                                         gint64 n,
+                                         GError **error)
+{
+  return garrow_array_builder_append_nulls<arrow::Date32Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     n,
+     error,
+     "[date32-array-builder][append-nulls]");
+}
+
 
 G_DEFINE_TYPE(GArrowDate64ArrayBuilder,
               garrow_date64_array_builder,
@@ -1298,6 +2175,44 @@ garrow_date64_array_builder_append(GArrowDate64ArrayBuilder *builder,
 }
 
 /**
+ * garrow_date64_array_builder_append_values:
+ * @builder: A #GArrowDate64ArrayBuilder.
+ * @values: (array length=values_length): The array of
+ *   the number of milliseconds since UNIX epoch in signed 64bit integer.
+ * @values_length: The length of `values`.
+ * @is_valids: (nullable) (array length=is_valids_length): The array of
+ *   boolean that shows whether the Nth value is valid or not. If the
+ *   Nth `is_valids` is %TRUE, the Nth `values` is valid value. Otherwise
+ *   the Nth value is null value.
+ * @is_valids_length: The length of `is_valids`.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Append multiple values at once. It's efficient than multiple
+ * `append()` and `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_date64_array_builder_append_values(GArrowDate64ArrayBuilder *builder,
+                                          const gint64 *values,
+                                          gint64 values_length,
+                                          const gboolean *is_valids,
+                                          gint64 is_valids_length,
+                                          GError **error)
+{
+  return garrow_array_builder_append_values<arrow::Date64Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     reinterpret_cast<const int64_t *>(values),
+     values_length,
+     is_valids,
+     is_valids_length,
+     error,
+     "[date64-array-builder][append-values]");
+}
+
+/**
  * garrow_date64_array_builder_append_null:
  * @builder: A #GArrowDate64ArrayBuilder.
  * @error: (nullable): Return location for a #GError or %NULL.
@@ -1316,6 +2231,31 @@ garrow_date64_array_builder_append_null(GArrowDate64ArrayBuilder *builder,
      "[date64-array-builder][append-null]");
 }
 
+/**
+ * garrow_date64_array_builder_append_nulls:
+ * @builder: A #GArrowDate64ArrayBuilder.
+ * @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 efficient than multiple
+ * `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_date64_array_builder_append_nulls(GArrowDate64ArrayBuilder *builder,
+                                         gint64 n,
+                                         GError **error)
+{
+  return garrow_array_builder_append_nulls<arrow::Date64Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     n,
+     error,
+     "[date64-array-builder][append-nulls]");
+}
+
 
 G_DEFINE_TYPE(GArrowTimestampArrayBuilder,
               garrow_timestamp_array_builder,
@@ -1372,6 +2312,44 @@ garrow_timestamp_array_builder_append(GArrowTimestampArrayBuilder *builder,
 }
 
 /**
+ * garrow_timestamp_array_builder_append_values:
+ * @builder: A #GArrowTimestampArrayBuilder.
+ * @values: (array length=values_length): The array of
+ *   the number of milliseconds since UNIX epoch in signed 64bit integer.
+ * @values_length: The length of `values`.
+ * @is_valids: (nullable) (array length=is_valids_length): The array of
+ *   boolean that shows whether the Nth value is valid or not. If the
+ *   Nth `is_valids` is %TRUE, the Nth `values` is valid value. Otherwise
+ *   the Nth value is null value.
+ * @is_valids_length: The length of `is_valids`.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Append multiple values at once. It's efficient than multiple
+ * `append()` and `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_timestamp_array_builder_append_values(GArrowTimestampArrayBuilder *builder,
+                                             const gint64 *values,
+                                             gint64 values_length,
+                                             const gboolean *is_valids,
+                                             gint64 is_valids_length,
+                                             GError **error)
+{
+  return garrow_array_builder_append_values<arrow::TimestampBuilder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     reinterpret_cast<const int64_t *>(values),
+     values_length,
+     is_valids,
+     is_valids_length,
+     error,
+     "[timestamp-array-builder][append-values]");
+}
+
+/**
  * garrow_timestamp_array_builder_append_null:
  * @builder: A #GArrowTimestampArrayBuilder.
  * @error: (nullable): Return location for a #GError or %NULL.
@@ -1390,6 +2368,31 @@ garrow_timestamp_array_builder_append_null(GArrowTimestampArrayBuilder *builder,
      "[timestamp-array-builder][append-null]");
 }
 
+/**
+ * garrow_timestamp_array_builder_append_nulls:
+ * @builder: A #GArrowTimestampArrayBuilder.
+ * @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 efficient than multiple
+ * `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_timestamp_array_builder_append_nulls(GArrowTimestampArrayBuilder *builder,
+                                            gint64 n,
+                                            GError **error)
+{
+  return garrow_array_builder_append_nulls<arrow::TimestampBuilder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     n,
+     error,
+     "[timestamp-array-builder][append-nulls]");
+}
+
 
 G_DEFINE_TYPE(GArrowTime32ArrayBuilder,
               garrow_time32_array_builder,
@@ -1446,6 +2449,44 @@ garrow_time32_array_builder_append(GArrowTime32ArrayBuilder *builder,
 }
 
 /**
+ * garrow_time32_array_builder_append_values:
+ * @builder: A #GArrowTime32ArrayBuilder.
+ * @values: (array length=values_length): The array of
+ *   the number of days since UNIX epoch in signed 32bit integer.
+ * @values_length: The length of `values`.
+ * @is_valids: (nullable) (array length=is_valids_length): The array of
+ *   boolean that shows whether the Nth value is valid or not. If the
+ *   Nth `is_valids` is %TRUE, the Nth `values` is valid value. Otherwise
+ *   the Nth value is null value.
+ * @is_valids_length: The length of `is_valids`.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Append multiple values at once. It's efficient than multiple
+ * `append()` and `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_time32_array_builder_append_values(GArrowTime32ArrayBuilder *builder,
+                                          const gint32 *values,
+                                          gint64 values_length,
+                                          const gboolean *is_valids,
+                                          gint64 is_valids_length,
+                                          GError **error)
+{
+  return garrow_array_builder_append_values<arrow::Time32Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     values,
+     values_length,
+     is_valids,
+     is_valids_length,
+     error,
+     "[time32-array-builder][append-values]");
+}
+
+/**
  * garrow_time32_array_builder_append_null:
  * @builder: A #GArrowTime32ArrayBuilder.
  * @error: (nullable): Return location for a #GError or %NULL.
@@ -1464,6 +2505,31 @@ garrow_time32_array_builder_append_null(GArrowTime32ArrayBuilder *builder,
      "[time32-array-builder][append-null]");
 }
 
+/**
+ * garrow_time32_array_builder_append_nulls:
+ * @builder: A #GArrowTime32ArrayBuilder.
+ * @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 efficient than multiple
+ * `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_time32_array_builder_append_nulls(GArrowTime32ArrayBuilder *builder,
+                                         gint64 n,
+                                         GError **error)
+{
+  return garrow_array_builder_append_nulls<arrow::Time32Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     n,
+     error,
+     "[time32-array-builder][append-nulls]");
+}
+
 
 G_DEFINE_TYPE(GArrowTime64ArrayBuilder,
               garrow_time64_array_builder,
@@ -1520,6 +2586,44 @@ garrow_time64_array_builder_append(GArrowTime64ArrayBuilder *builder,
 }
 
 /**
+ * garrow_time64_array_builder_append_values:
+ * @builder: A #GArrowTime64ArrayBuilder.
+ * @values: (array length=values_length): The array of
+ *   the number of milliseconds since UNIX epoch in signed 64bit integer.
+ * @values_length: The length of `values`.
+ * @is_valids: (nullable) (array length=is_valids_length): The array of
+ *   boolean that shows whether the Nth value is valid or not. If the
+ *   Nth `is_valids` is %TRUE, the Nth `values` is valid value. Otherwise
+ *   the Nth value is null value.
+ * @is_valids_length: The length of `is_valids`.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Append multiple values at once. It's efficient than multiple
+ * `append()` and `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_time64_array_builder_append_values(GArrowTime64ArrayBuilder *builder,
+                                          const gint64 *values,
+                                          gint64 values_length,
+                                          const gboolean *is_valids,
+                                          gint64 is_valids_length,
+                                          GError **error)
+{
+  return garrow_array_builder_append_values<arrow::Time64Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     reinterpret_cast<const int64_t *>(values),
+     values_length,
+     is_valids,
+     is_valids_length,
+     error,
+     "[time64-array-builder][append-values]");
+}
+
+/**
  * garrow_time64_array_builder_append_null:
  * @builder: A #GArrowTime64ArrayBuilder.
  * @error: (nullable): Return location for a #GError or %NULL.
@@ -1538,6 +2642,31 @@ garrow_time64_array_builder_append_null(GArrowTime64ArrayBuilder *builder,
      "[time64-array-builder][append-null]");
 }
 
+/**
+ * garrow_time64_array_builder_append_nulls:
+ * @builder: A #GArrowTime64ArrayBuilder.
+ * @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 efficient than multiple
+ * `append_null()` calls.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_time64_array_builder_append_nulls(GArrowTime64ArrayBuilder *builder,
+                                         gint64 n,
+                                         GError **error)
+{
+  return garrow_array_builder_append_nulls<arrow::Time64Builder *>
+    (GARROW_ARRAY_BUILDER(builder),
+     n,
+     error,
+     "[time64-array-builder][append-nulls]");
+}
+
 
 typedef struct GArrowListArrayBuilderPrivate_ {
   GArrowArrayBuilder *value_builder;

http://git-wip-us.apache.org/repos/asf/arrow/blob/4a65fea0/c_glib/arrow-glib/array-builder.h
----------------------------------------------------------------------
diff --git a/c_glib/arrow-glib/array-builder.h b/c_glib/arrow-glib/array-builder.h
index f28959f..8780854 100644
--- a/c_glib/arrow-glib/array-builder.h
+++ b/c_glib/arrow-glib/array-builder.h
@@ -116,8 +116,17 @@ GArrowBooleanArrayBuilder *garrow_boolean_array_builder_new(void);
 gboolean garrow_boolean_array_builder_append(GArrowBooleanArrayBuilder *builder,
                                              gboolean value,
                                              GError **error);
+gboolean garrow_boolean_array_builder_append_values(GArrowBooleanArrayBuilder *builder,
+                                                    const gboolean *values,
+                                                    gint64 values_length,
+                                                    const gboolean *is_valids,
+                                                    gint64 is_valids_length,
+                                                    GError **error);
 gboolean garrow_boolean_array_builder_append_null(GArrowBooleanArrayBuilder *builder,
                                                   GError **error);
+gboolean garrow_boolean_array_builder_append_nulls(GArrowBooleanArrayBuilder *builder,
+                                                   gint64 n,
+                                                   GError **error);
 
 
 #define GARROW_TYPE_INT_ARRAY_BUILDER           \
@@ -167,8 +176,17 @@ GArrowIntArrayBuilder *garrow_int_array_builder_new(void);
 gboolean garrow_int_array_builder_append(GArrowIntArrayBuilder *builder,
                                          gint64 value,
                                          GError **error);
+gboolean garrow_int_array_builder_append_values(GArrowIntArrayBuilder *builder,
+                                                const gint64 *values,
+                                                gint64 values_length,
+                                                const gboolean *is_valids,
+                                                gint64 is_valids_length,
+                                                GError **error);
 gboolean garrow_int_array_builder_append_null(GArrowIntArrayBuilder *builder,
                                               GError **error);
+gboolean garrow_int_array_builder_append_nulls(GArrowIntArrayBuilder *builder,
+                                               gint64 n,
+                                               GError **error);
 
 
 #define GARROW_TYPE_INT8_ARRAY_BUILDER          \
@@ -218,8 +236,17 @@ GArrowInt8ArrayBuilder *garrow_int8_array_builder_new(void);
 gboolean garrow_int8_array_builder_append(GArrowInt8ArrayBuilder *builder,
                                           gint8 value,
                                           GError **error);
+gboolean garrow_int8_array_builder_append_values(GArrowInt8ArrayBuilder *builder,
+                                                 const gint8 *values,
+                                                 gint64 values_length,
+                                                 const gboolean *is_valids,
+                                                 gint64 is_valids_length,
+                                                 GError **error);
 gboolean garrow_int8_array_builder_append_null(GArrowInt8ArrayBuilder *builder,
                                                GError **error);
+gboolean garrow_int8_array_builder_append_nulls(GArrowInt8ArrayBuilder *builder,
+                                                gint64 n,
+                                                GError **error);
 
 
 #define GARROW_TYPE_UINT8_ARRAY_BUILDER         \
@@ -269,8 +296,17 @@ GArrowUInt8ArrayBuilder *garrow_uint8_array_builder_new(void);
 gboolean garrow_uint8_array_builder_append(GArrowUInt8ArrayBuilder *builder,
                                            guint8 value,
                                            GError **error);
+gboolean garrow_uint8_array_builder_append_values(GArrowUInt8ArrayBuilder *builder,
+                                                  const guint8 *values,
+                                                  gint64 values_length,
+                                                  const gboolean *is_valids,
+                                                  gint64 is_valids_length,
+                                                  GError **error);
 gboolean garrow_uint8_array_builder_append_null(GArrowUInt8ArrayBuilder *builder,
                                                 GError **error);
+gboolean garrow_uint8_array_builder_append_nulls(GArrowUInt8ArrayBuilder *builder,
+                                                 gint64 n,
+                                                 GError **error);
 
 
 #define GARROW_TYPE_INT16_ARRAY_BUILDER         \
@@ -320,8 +356,17 @@ GArrowInt16ArrayBuilder *garrow_int16_array_builder_new(void);
 gboolean garrow_int16_array_builder_append(GArrowInt16ArrayBuilder *builder,
                                            gint16 value,
                                            GError **error);
+gboolean garrow_int16_array_builder_append_values(GArrowInt16ArrayBuilder *builder,
+                                                  const gint16 *values,
+                                                  gint64 values_length,
+                                                  const gboolean *is_valids,
+                                                  gint64 is_valids_length,
+                                                  GError **error);
 gboolean garrow_int16_array_builder_append_null(GArrowInt16ArrayBuilder *builder,
                                                 GError **error);
+gboolean garrow_int16_array_builder_append_nulls(GArrowInt16ArrayBuilder *builder,
+                                                 gint64 n,
+                                                 GError **error);
 
 
 #define GARROW_TYPE_UINT16_ARRAY_BUILDER        \
@@ -371,8 +416,17 @@ GArrowUInt16ArrayBuilder *garrow_uint16_array_builder_new(void);
 gboolean garrow_uint16_array_builder_append(GArrowUInt16ArrayBuilder *builder,
                                             guint16 value,
                                             GError **error);
+gboolean garrow_uint16_array_builder_append_values(GArrowUInt16ArrayBuilder *builder,
+                                                   const guint16 *values,
+                                                   gint64 values_length,
+                                                   const gboolean *is_valids,
+                                                   gint64 is_valids_length,
+                                                   GError **error);
 gboolean garrow_uint16_array_builder_append_null(GArrowUInt16ArrayBuilder *builder,
                                                  GError **error);
+gboolean garrow_uint16_array_builder_append_nulls(GArrowUInt16ArrayBuilder *builder,
+                                                  gint64 n,
+                                                  GError **error);
 
 
 #define GARROW_TYPE_INT32_ARRAY_BUILDER         \
@@ -422,8 +476,17 @@ GArrowInt32ArrayBuilder *garrow_int32_array_builder_new(void);
 gboolean garrow_int32_array_builder_append(GArrowInt32ArrayBuilder *builder,
                                            gint32 value,
                                            GError **error);
+gboolean garrow_int32_array_builder_append_values(GArrowInt32ArrayBuilder *builder,
+                                                  const gint32 *values,
+                                                  gint64 values_length,
+                                                  const gboolean *is_valids,
+                                                  gint64 is_valids_length,
+                                                  GError **error);
 gboolean garrow_int32_array_builder_append_null(GArrowInt32ArrayBuilder *builder,
                                                 GError **error);
+gboolean garrow_int32_array_builder_append_nulls(GArrowInt32ArrayBuilder *builder,
+                                                 gint64 n,
+                                                 GError **error);
 
 
 #define GARROW_TYPE_UINT32_ARRAY_BUILDER        \
@@ -473,8 +536,17 @@ GArrowUInt32ArrayBuilder *garrow_uint32_array_builder_new(void);
 gboolean garrow_uint32_array_builder_append(GArrowUInt32ArrayBuilder *builder,
                                             guint32 value,
                                             GError **error);
+gboolean garrow_uint32_array_builder_append_values(GArrowUInt32ArrayBuilder *builder,
+                                                   const guint32 *values,
+                                                   gint64 values_length,
+                                                   const gboolean *is_valids,
+                                                   gint64 is_valids_length,
+                                                   GError **error);
 gboolean garrow_uint32_array_builder_append_null(GArrowUInt32ArrayBuilder *builder,
                                                  GError **error);
+gboolean garrow_uint32_array_builder_append_nulls(GArrowUInt32ArrayBuilder *builder,
+                                                  gint64 n,
+                                                  GError **error);
 
 
 #define GARROW_TYPE_INT64_ARRAY_BUILDER         \
@@ -524,8 +596,17 @@ GArrowInt64ArrayBuilder *garrow_int64_array_builder_new(void);
 gboolean garrow_int64_array_builder_append(GArrowInt64ArrayBuilder *builder,
                                            gint64 value,
                                            GError **error);
+gboolean garrow_int64_array_builder_append_values(GArrowInt64ArrayBuilder *builder,
+                                                  const gint64 *values,
+                                                  gint64 values_length,
+                                                  const gboolean *is_valids,
+                                                  gint64 is_valids_length,
+                                                  GError **error);
 gboolean garrow_int64_array_builder_append_null(GArrowInt64ArrayBuilder *builder,
                                                 GError **error);
+gboolean garrow_int64_array_builder_append_nulls(GArrowInt64ArrayBuilder *builder,
+                                                 gint64 n,
+                                                 GError **error);
 
 
 #define GARROW_TYPE_UINT64_ARRAY_BUILDER        \
@@ -575,8 +656,17 @@ GArrowUInt64ArrayBuilder *garrow_uint64_array_builder_new(void);
 gboolean garrow_uint64_array_builder_append(GArrowUInt64ArrayBuilder *builder,
                                             guint64 value,
                                             GError **error);
+gboolean garrow_uint64_array_builder_append_values(GArrowUInt64ArrayBuilder *builder,
+                                                   const guint64 *values,
+                                                   gint64 values_length,
+                                                   const gboolean *is_valids,
+                                                   gint64 is_valids_length,
+                                                   GError **error);
 gboolean garrow_uint64_array_builder_append_null(GArrowUInt64ArrayBuilder *builder,
                                                  GError **error);
+gboolean garrow_uint64_array_builder_append_nulls(GArrowUInt64ArrayBuilder *builder,
+                                                  gint64 n,
+                                                  GError **error);
 
 
 #define GARROW_TYPE_FLOAT_ARRAY_BUILDER         \
@@ -626,8 +716,17 @@ GArrowFloatArrayBuilder *garrow_float_array_builder_new(void);
 gboolean garrow_float_array_builder_append(GArrowFloatArrayBuilder *builder,
                                            gfloat value,
                                            GError **error);
+gboolean garrow_float_array_builder_append_values(GArrowFloatArrayBuilder *builder,
+                                                  const gfloat *values,
+                                                  gint64 values_length,
+                                                  const gboolean *is_valids,
+                                                  gint64 is_valids_length,
+                                                  GError **error);
 gboolean garrow_float_array_builder_append_null(GArrowFloatArrayBuilder *builder,
                                                 GError **error);
+gboolean garrow_float_array_builder_append_nulls(GArrowFloatArrayBuilder *builder,
+                                                 gint64 n,
+                                                 GError **error);
 
 
 #define GARROW_TYPE_DOUBLE_ARRAY_BUILDER        \
@@ -677,8 +776,17 @@ GArrowDoubleArrayBuilder *garrow_double_array_builder_new(void);
 gboolean garrow_double_array_builder_append(GArrowDoubleArrayBuilder *builder,
                                             gdouble value,
                                             GError **error);
+gboolean garrow_double_array_builder_append_values(GArrowDoubleArrayBuilder *builder,
+                                                   const gdouble *values,
+                                                   gint64 values_length,
+                                                   const gboolean *is_valids,
+                                                   gint64 is_valids_length,
+                                                   GError **error);
 gboolean garrow_double_array_builder_append_null(GArrowDoubleArrayBuilder *builder,
                                                  GError **error);
+gboolean garrow_double_array_builder_append_nulls(GArrowDoubleArrayBuilder *builder,
+                                                  gint64 n,
+                                                  GError **error);
 
 
 #define GARROW_TYPE_BINARY_ARRAY_BUILDER        \
@@ -829,8 +937,17 @@ GArrowDate32ArrayBuilder *garrow_date32_array_builder_new(void);
 gboolean garrow_date32_array_builder_append(GArrowDate32ArrayBuilder *builder,
                                             gint32 value,
                                             GError **error);
+gboolean garrow_date32_array_builder_append_values(GArrowDate32ArrayBuilder *builder,
+                                                   const gint32 *values,
+                                                   gint64 values_length,
+                                                   const gboolean *is_valids,
+                                                   gint64 is_valids_length,
+                                                   GError **error);
 gboolean garrow_date32_array_builder_append_null(GArrowDate32ArrayBuilder *builder,
                                                  GError **error);
+gboolean garrow_date32_array_builder_append_nulls(GArrowDate32ArrayBuilder *builder,
+                                                  gint64 n,
+                                                  GError **error);
 
 
 #define GARROW_TYPE_DATE64_ARRAY_BUILDER        \
@@ -880,8 +997,17 @@ GArrowDate64ArrayBuilder *garrow_date64_array_builder_new(void);
 gboolean garrow_date64_array_builder_append(GArrowDate64ArrayBuilder *builder,
                                             gint64 value,
                                             GError **error);
+gboolean garrow_date64_array_builder_append_values(GArrowDate64ArrayBuilder *builder,
+                                                   const gint64 *values,
+                                                   gint64 values_length,
+                                                   const gboolean *is_valids,
+                                                   gint64 is_valids_length,
+                                                   GError **error);
 gboolean garrow_date64_array_builder_append_null(GArrowDate64ArrayBuilder *builder,
                                                  GError **error);
+gboolean garrow_date64_array_builder_append_nulls(GArrowDate64ArrayBuilder *builder,
+                                                  gint64 n,
+                                                  GError **error);
 
 
 #define GARROW_TYPE_TIMESTAMP_ARRAY_BUILDER     \
@@ -932,8 +1058,17 @@ garrow_timestamp_array_builder_new(GArrowTimestampDataType *data_type);
 gboolean garrow_timestamp_array_builder_append(GArrowTimestampArrayBuilder *builder,
                                                gint64 value,
                                                GError **error);
+gboolean garrow_timestamp_array_builder_append_values(GArrowTimestampArrayBuilder *builder,
+                                                      const gint64 *values,
+                                                      gint64 values_length,
+                                                      const gboolean *is_valids,
+                                                      gint64 is_valids_length,
+                                                      GError **error);
 gboolean garrow_timestamp_array_builder_append_null(GArrowTimestampArrayBuilder *builder,
                                                     GError **error);
+gboolean garrow_timestamp_array_builder_append_nulls(GArrowTimestampArrayBuilder *builder,
+                                                     gint64 n,
+                                                     GError **error);
 
 
 #define GARROW_TYPE_TIME32_ARRAY_BUILDER        \
@@ -983,8 +1118,17 @@ GArrowTime32ArrayBuilder *garrow_time32_array_builder_new(GArrowTime32DataType *
 gboolean garrow_time32_array_builder_append(GArrowTime32ArrayBuilder *builder,
                                             gint32 value,
                                             GError **error);
+gboolean garrow_time32_array_builder_append_values(GArrowTime32ArrayBuilder *builder,
+                                                   const gint32 *values,
+                                                   gint64 values_length,
+                                                   const gboolean *is_valids,
+                                                   gint64 is_valids_length,
+                                                   GError **error);
 gboolean garrow_time32_array_builder_append_null(GArrowTime32ArrayBuilder *builder,
                                                  GError **error);
+gboolean garrow_time32_array_builder_append_nulls(GArrowTime32ArrayBuilder *builder,
+                                                  gint64 n,
+                                                  GError **error);
 
 
 #define GARROW_TYPE_TIME64_ARRAY_BUILDER        \
@@ -1034,8 +1178,17 @@ GArrowTime64ArrayBuilder *garrow_time64_array_builder_new(GArrowTime64DataType *
 gboolean garrow_time64_array_builder_append(GArrowTime64ArrayBuilder *builder,
                                             gint64 value,
                                             GError **error);
+gboolean garrow_time64_array_builder_append_values(GArrowTime64ArrayBuilder *builder,
+                                                   const gint64 *values,
+                                                   gint64 values_length,
+                                                   const gboolean *is_valids,
+                                                   gint64 is_valids_length,
+                                                   GError **error);
 gboolean garrow_time64_array_builder_append_null(GArrowTime64ArrayBuilder *builder,
                                                  GError **error);
+gboolean garrow_time64_array_builder_append_nulls(GArrowTime64ArrayBuilder *builder,
+                                                  gint64 n,
+                                                  GError **error);
 
 
 #define GARROW_TYPE_LIST_ARRAY_BUILDER          \

http://git-wip-us.apache.org/repos/asf/arrow/blob/4a65fea0/c_glib/doc/reference/arrow-glib-docs.sgml
----------------------------------------------------------------------
diff --git a/c_glib/doc/reference/arrow-glib-docs.sgml b/c_glib/doc/reference/arrow-glib-docs.sgml
index 3366fc8..fc161a5 100644
--- a/c_glib/doc/reference/arrow-glib-docs.sgml
+++ b/c_glib/doc/reference/arrow-glib-docs.sgml
@@ -133,6 +133,10 @@
     <title>Index of deprecated API</title>
     <xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
   </index>
+  <index id="api-index-0-8-0" role="0.8.0">
+    <title>Index of new symbols in 0.8.0</title>
+    <xi:include href="xml/api-index-0.8.0.xml"><xi:fallback /></xi:include>
+  </index>
   <index id="api-index-0-7-0" role="0.7.0">
     <title>Index of new symbols in 0.7.0</title>
     <xi:include href="xml/api-index-0.7.0.xml"><xi:fallback /></xi:include>

http://git-wip-us.apache.org/repos/asf/arrow/blob/4a65fea0/c_glib/test/test-array-builder.rb
----------------------------------------------------------------------
diff --git a/c_glib/test/test-array-builder.rb b/c_glib/test/test-array-builder.rb
new file mode 100644
index 0000000..6c0f984
--- /dev/null
+++ b/c_glib/test/test-array-builder.rb
@@ -0,0 +1,485 @@
+# 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 ArrayBuilderAppendValuesTests
+  def test_empty
+    builder = create_builder
+    builder.append_values([])
+    assert_equal(build_array([]),
+                 builder.finish)
+  end
+
+  def test_values_only
+    builder = create_builder
+    builder.append_values(sample_values)
+    assert_equal(build_array(sample_values),
+                 builder.finish)
+  end
+
+  def test_with_is_valids
+    builder = create_builder
+    builder.append_values(sample_values, [true, true, false])
+    sample_values_with_null = sample_values
+    sample_values_with_null[2] = nil
+    assert_equal(build_array(sample_values_with_null),
+                 builder.finish)
+  end
+
+  def test_mismatch_length
+    builder = create_builder
+    message = "[#{builder_class_name}][append-values]: " +
+      "values length and is_valids length must be equal: <3> != <2>"
+    assert_raise(Arrow::Error::Invalid.new(message)) do
+      builder.append_values(sample_values, [true, true])
+    end
+  end
+end
+
+module ArrayBuilderAppendNullsTests
+  def test_zero
+    builder = create_builder
+    builder.append_nulls(0)
+    assert_equal(build_array([]),
+                 builder.finish)
+  end
+
+  def test_positive
+    builder = create_builder
+    builder.append_nulls(3)
+    assert_equal(build_array([nil, nil, nil]),
+                 builder.finish)
+  end
+
+  def test_negative
+    builder = create_builder
+    message = "[#{builder_class_name}][append-nulls]: " +
+      "the number of nulls must be 0 or larger: <-1>"
+    assert_raise(Arrow::Error::Invalid.new(message)) do
+      builder.append_nulls(-1)
+    end
+  end
+end
+
+class TestArrayBuilder < Test::Unit::TestCase
+  include Helper::Buildable
+  include Helper::Omittable
+
+  def setup
+    require_gi_bindings(3, 1, 9)
+  end
+
+  def build_array(values)
+    super(create_builder, values)
+  end
+
+  sub_test_case("BooleanArrayBuilder") do
+    def create_builder
+      Arrow::BooleanArrayBuilder.new
+    end
+
+    def builder_class_name
+      "boolean-array-builder"
+    end
+
+    def sample_values
+      [true, false, true]
+    end
+
+    sub_test_case("#append_values") do
+      include ArrayBuilderAppendValuesTests
+    end
+
+    sub_test_case("#append_nulls") do
+      include ArrayBuilderAppendNullsTests
+    end
+  end
+
+  sub_test_case("IntArrayBuilder") do
+    def create_builder
+      Arrow::IntArrayBuilder.new
+    end
+
+    def builder_class_name
+      "int-array-builder"
+    end
+
+    def sample_values
+      [1, -2, 3]
+    end
+
+    sub_test_case("#append_values") do
+      include ArrayBuilderAppendValuesTests
+    end
+
+    sub_test_case("#append_nulls") do
+      include ArrayBuilderAppendNullsTests
+    end
+  end
+
+  sub_test_case("Int8ArrayBuilder") do
+    def create_builder
+      Arrow::Int8ArrayBuilder.new
+    end
+
+    def builder_class_name
+      "int8-array-builder"
+    end
+
+    def sample_values
+      [1, -2, 3]
+    end
+
+    sub_test_case("#append_values") do
+      include ArrayBuilderAppendValuesTests
+    end
+
+    sub_test_case("#append_nulls") do
+      include ArrayBuilderAppendNullsTests
+    end
+  end
+
+  sub_test_case("UInt8ArrayBuilder") do
+    def create_builder
+      Arrow::UInt8ArrayBuilder.new
+    end
+
+    def builder_class_name
+      "uint8-array-builder"
+    end
+
+    def sample_values
+      [1, 2, 3]
+    end
+
+    sub_test_case("#append_values") do
+      include ArrayBuilderAppendValuesTests
+    end
+
+    sub_test_case("#append_nulls") do
+      include ArrayBuilderAppendNullsTests
+    end
+  end
+
+  sub_test_case("Int16ArrayBuilder") do
+    def create_builder
+      Arrow::Int16ArrayBuilder.new
+    end
+
+    def builder_class_name
+      "int16-array-builder"
+    end
+
+    def sample_values
+      [1, -2, 3]
+    end
+
+    sub_test_case("#append_values") do
+      include ArrayBuilderAppendValuesTests
+    end
+
+    sub_test_case("#append_nulls") do
+      include ArrayBuilderAppendNullsTests
+    end
+  end
+
+  sub_test_case("UInt16ArrayBuilder") do
+    def create_builder
+      Arrow::UInt16ArrayBuilder.new
+    end
+
+    def builder_class_name
+      "uint16-array-builder"
+    end
+
+    def sample_values
+      [1, 2, 3]
+    end
+
+    sub_test_case("#append_values") do
+      include ArrayBuilderAppendValuesTests
+    end
+
+    sub_test_case("#append_nulls") do
+      include ArrayBuilderAppendNullsTests
+    end
+  end
+
+  sub_test_case("Int32ArrayBuilder") do
+    def create_builder
+      Arrow::Int32ArrayBuilder.new
+    end
+
+    def builder_class_name
+      "int32-array-builder"
+    end
+
+    def sample_values
+      [1, -2, 3]
+    end
+
+    sub_test_case("#append_values") do
+      include ArrayBuilderAppendValuesTests
+    end
+
+    sub_test_case("#append_nulls") do
+      include ArrayBuilderAppendNullsTests
+    end
+  end
+
+  sub_test_case("UInt32ArrayBuilder") do
+    def create_builder
+      Arrow::UInt32ArrayBuilder.new
+    end
+
+    def builder_class_name
+      "uint32-array-builder"
+    end
+
+    def sample_values
+      [1, 2, 3]
+    end
+
+    sub_test_case("#append_values") do
+      include ArrayBuilderAppendValuesTests
+    end
+
+    sub_test_case("#append_nulls") do
+      include ArrayBuilderAppendNullsTests
+    end
+  end
+
+  sub_test_case("Int64ArrayBuilder") do
+    def create_builder
+      Arrow::Int64ArrayBuilder.new
+    end
+
+    def builder_class_name
+      "int64-array-builder"
+    end
+
+    def sample_values
+      [1, -2, 3]
+    end
+
+    sub_test_case("#append_values") do
+      include ArrayBuilderAppendValuesTests
+    end
+
+    sub_test_case("#append_nulls") do
+      include ArrayBuilderAppendNullsTests
+    end
+  end
+
+  sub_test_case("UInt64ArrayBuilder") do
+    def create_builder
+      Arrow::UInt64ArrayBuilder.new
+    end
+
+    def builder_class_name
+      "uint64-array-builder"
+    end
+
+    def sample_values
+      [1, 2, 3]
+    end
+
+    sub_test_case("#append_values") do
+      include ArrayBuilderAppendValuesTests
+    end
+
+    sub_test_case("#append_nulls") do
+      include ArrayBuilderAppendNullsTests
+    end
+  end
+
+  sub_test_case("FloatArrayBuilder") do
+    def create_builder
+      Arrow::FloatArrayBuilder.new
+    end
+
+    def builder_class_name
+      "float-array-builder"
+    end
+
+    def sample_values
+      [1.1, -2.2, 3.3]
+    end
+
+    sub_test_case("#append_values") do
+      include ArrayBuilderAppendValuesTests
+    end
+
+    sub_test_case("#append_nulls") do
+      include ArrayBuilderAppendNullsTests
+    end
+  end
+
+  sub_test_case("DoubleArrayBuilder") do
+    def create_builder
+      Arrow::DoubleArrayBuilder.new
+    end
+
+    def builder_class_name
+      "double-array-builder"
+    end
+
+    def sample_values
+      [1.1, -2.2, 3.3]
+    end
+
+    sub_test_case("#append_values") do
+      include ArrayBuilderAppendValuesTests
+    end
+
+    sub_test_case("#append_nulls") do
+      include ArrayBuilderAppendNullsTests
+    end
+  end
+
+  sub_test_case("Date32ArrayBuilder") do
+    def create_builder
+      Arrow::Date32ArrayBuilder.new
+    end
+
+    def builder_class_name
+      "date32-array-builder"
+    end
+
+    def sample_values
+      [
+        0,     # epoch
+        17406, # 2017-08-28
+        17427, # 2017-09-18
+      ]
+    end
+
+    sub_test_case("#append_values") do
+      include ArrayBuilderAppendValuesTests
+    end
+
+    sub_test_case("#append_nulls") do
+      include ArrayBuilderAppendNullsTests
+    end
+  end
+
+  sub_test_case("Date64ArrayBuilder") do
+    def create_builder
+      Arrow::Date64ArrayBuilder.new
+    end
+
+    def builder_class_name
+      "date64-array-builder"
+    end
+
+    def sample_values
+      [
+        -315619200,    # 1960-01-01T00:00:00Z
+        0,             # epoch
+        1503878400000, # 2017-08-28T00:00:00Z
+      ]
+    end
+
+    sub_test_case("#append_values") do
+      include ArrayBuilderAppendValuesTests
+    end
+
+    sub_test_case("#append_nulls") do
+      include ArrayBuilderAppendNullsTests
+    end
+  end
+
+  sub_test_case("TimestampArrayBuilder") do
+    def create_builder
+      data_type = Arrow::TimestampDataType.new(:milli)
+      Arrow::TimestampArrayBuilder.new(data_type)
+    end
+
+    def builder_class_name
+      "timestamp-array-builder"
+    end
+
+    def sample_values
+      [
+        0,             # epoch
+        1504953190854, # 2017-09-09T10:33:10.854Z
+        1505660812942, # 2017-09-17T15:06:52.942Z
+      ]
+    end
+
+    sub_test_case("#append_values") do
+      include ArrayBuilderAppendValuesTests
+    end
+
+    sub_test_case("#append_nulls") do
+      include ArrayBuilderAppendNullsTests
+    end
+  end
+
+  sub_test_case("Time32ArrayBuilder") do
+    def create_builder
+      data_type = Arrow::Time32DataType.new(:second)
+      Arrow::Time32ArrayBuilder.new(data_type)
+    end
+
+    def builder_class_name
+      "time32-array-builder"
+    end
+
+    def sample_values
+      [
+        0,                # midnight
+        60 * 10,          # 00:10:00
+        60 * 60 * 2 + 30, # 02:00:30
+      ]
+    end
+
+    sub_test_case("#append_values") do
+      include ArrayBuilderAppendValuesTests
+    end
+
+    sub_test_case("#append_nulls") do
+      include ArrayBuilderAppendNullsTests
+    end
+  end
+
+  sub_test_case("Time64ArrayBuilder") do
+    def create_builder
+      data_type = Arrow::Time64DataType.new(:micro)
+      Arrow::Time64ArrayBuilder.new(data_type)
+    end
+
+    def builder_class_name
+      "time64-array-builder"
+    end
+
+    def sample_values
+      [
+        0,                                # midnight
+        60 * 10 * 1000 * 1000,            # 00:10:00.000000
+        (60 * 60 * 2 + 30) * 1000 * 1000, # 02:00:30.000000
+      ]
+    end
+
+    sub_test_case("#append_values") do
+      include ArrayBuilderAppendValuesTests
+    end
+
+    sub_test_case("#append_nulls") do
+      include ArrayBuilderAppendNullsTests
+    end
+  end
+end