You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ko...@apache.org on 2022/05/09 01:48:18 UTC

[arrow] branch master updated: ARROW-15671: [GLib] Add support for Vala

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 953a6ded05 ARROW-15671: [GLib] Add support for Vala
953a6ded05 is described below

commit 953a6ded05dd5f832d2757b1b4eab51cb35349b6
Author: Sutou Kouhei <ko...@clear-code.com>
AuthorDate: Mon May 9 10:48:02 2022 +0900

    ARROW-15671: [GLib] Add support for Vala
    
    Closes #12993 from kou/glib-vapi
    
    Lead-authored-by: Sutou Kouhei <ko...@clear-code.com>
    Co-authored-by: Tao Zuhong <ta...@users.noreply.github.com>
    Signed-off-by: Sutou Kouhei <ko...@clear-code.com>
---
 .dir-locals.el                                     |   7 +-
 c_glib/Brewfile                                    |   1 +
 c_glib/arrow-cuda-glib/meson.build                 |  39 +++--
 c_glib/arrow-dataset-glib/meson.build              |  44 ++++--
 c_glib/arrow-flight-glib/meson.build               |  44 ++++--
 c_glib/arrow-glib/Arrow-1.0.metadata               |  20 +++
 c_glib/arrow-glib/meson.build                      |  24 ++-
 c_glib/example/README.md                           |  12 +-
 c_glib/example/lua/README.md                       |  18 +--
 c_glib/example/lua/meson.build                     |   4 +-
 .../example/lua/{read-batch.lua => read-file.lua}  |   0
 .../lua/{write-batch.lua => write-file.lua}        |   0
 c_glib/example/meson.build                         |   5 +-
 c_glib/example/{read-batch.c => read-file.c}       |   2 +-
 c_glib/example/{lua => vala}/README.md             |  36 ++---
 c_glib/example/vala/build.vala                     |  47 ++++++
 c_glib/example/{lua => vala}/meson.build           |  36 ++++-
 c_glib/example/vala/read-file.vala                 | 170 ++++++++++++++++++++
 c_glib/example/vala/read-stream.vala               | 172 +++++++++++++++++++++
 c_glib/example/vala/write-file.vala                | 153 ++++++++++++++++++
 c_glib/example/vala/write-stream.vala              | 153 ++++++++++++++++++
 c_glib/gandiva-glib/meson.build                    |  44 ++++--
 c_glib/meson.build                                 |   4 +
 c_glib/meson_options.txt                           |   5 +
 c_glib/parquet-glib/meson.build                    |  44 ++++--
 c_glib/plasma-glib/meson.build                     |  40 +++--
 ci/docker/linux-apt-c-glib.dockerfile              |  12 +-
 ci/docker/linux-apt-docs.dockerfile                |   9 +-
 ci/scripts/c_glib_build.sh                         |   2 +
 ci/scripts/c_glib_test.sh                          |  22 ++-
 ci/scripts/msys2_setup.sh                          |   1 +
 dev/release/setup-rhel-rebuilds.sh                 |   1 +
 dev/release/verify-apt.sh                          |  37 +++--
 dev/release/verify-release-candidate.sh            |   2 +
 dev/release/verify-yum.sh                          |  38 ++++-
 dev/tasks/homebrew-formulae/apache-arrow-glib.rb   |   3 +-
 dev/tasks/linux-packages/Rakefile                  |   3 +-
 .../apache-arrow/apt/debian-bookworm/Dockerfile    |   1 +
 .../apache-arrow/apt/debian-bullseye/Dockerfile    |   1 +
 .../apache-arrow/apt/debian-buster/Dockerfile      |   1 +
 .../apache-arrow/apt/ubuntu-bionic/Dockerfile      |   1 +
 .../apache-arrow/apt/ubuntu-focal/Dockerfile       |   1 +
 .../apache-arrow/apt/ubuntu-impish/Dockerfile      |   1 +
 .../apache-arrow/apt/ubuntu-jammy/Dockerfile       |   1 +
 .../linux-packages/apache-arrow/debian/control.in  |   1 +
 .../debian/libarrow-cuda-glib-dev.install          |   1 +
 .../debian/libarrow-dataset-glib-dev.install       |   1 +
 .../debian/libarrow-flight-glib-dev.install        |   1 +
 .../apache-arrow/debian/libarrow-glib-dev.install  |   1 +
 .../debian/libgandiva-glib-dev.install             |   1 +
 .../debian/libparquet-glib-dev.install             |   1 +
 .../apache-arrow/debian/libplasma-glib-dev.install |   1 +
 dev/tasks/linux-packages/apache-arrow/debian/rules |   3 +-
 .../apache-arrow/yum/almalinux-8/Dockerfile        |   1 +
 .../apache-arrow/yum/amazon-linux-2/Dockerfile     |   1 +
 .../linux-packages/apache-arrow/yum/arrow.spec.in  |  10 +-
 .../apache-arrow/yum/centos-7/Dockerfile           |   1 +
 .../apache-arrow/yum/centos-8-stream/Dockerfile    |   1 +
 58 files changed, 1098 insertions(+), 188 deletions(-)

diff --git a/.dir-locals.el b/.dir-locals.el
index 06090cfe9c..2a2af98371 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -15,8 +15,9 @@
 ;;; specific language governing permissions and limitations
 ;;; under the License.
 
-((sh-mode . ((indent-tabs-mode . nil)
+((cmake-mode . ((indent-tabs-mode . nil)))
+ (powershell-mode . ((indent-tabs-mode . nil)))
+ (sh-mode . ((indent-tabs-mode . nil)
              (sh-indentation   . 2)
              (sh-basic-offset  . 2)))
- (cmake-mode . ((indent-tabs-mode . nil)))
- (powershell-mode . ((indent-tabs-mode . nil))))
+ (vala-mode . ((indent-tabs-mode . nil))))
diff --git a/c_glib/Brewfile b/c_glib/Brewfile
index ba65853a74..bfda23b374 100644
--- a/c_glib/Brewfile
+++ b/c_glib/Brewfile
@@ -20,3 +20,4 @@ brew "gobject-introspection"
 brew "gtk-doc"
 brew "libtool"
 brew "meson"
+brew "vala"
diff --git a/c_glib/arrow-cuda-glib/meson.build b/c_glib/arrow-cuda-glib/meson.build
index a655be0843..d9cd9c92e7 100644
--- a/c_glib/arrow-cuda-glib/meson.build
+++ b/c_glib/arrow-cuda-glib/meson.build
@@ -65,17 +65,30 @@ if have_gi
     '--warn-all',
     '--include-uninstalled=./arrow-glib/Arrow-1.0.gir',
   ]
-  arrow_cuda_glib_gir = gnome.generate_gir(libarrow_cuda_glib,
-                                           dependencies: gir_dependencies,
-                                           sources: sources + c_headers,
-                                           namespace: 'ArrowCUDA',
-                                           nsversion: api_version,
-                                           identifier_prefix: 'GArrowCUDA',
-                                           symbol_prefix: 'garrow_cuda',
-                                           export_packages: 'arrow-cuda-glib',
-                                           includes: [
-                                             'Arrow-1.0',
-                                           ],
-                                           install: true,
-                                           extra_args: gir_extra_args)
+  arrow_cuda_glib_gir = \
+    gnome.generate_gir(libarrow_cuda_glib,
+                       dependencies: gir_dependencies,
+                       export_packages: 'arrow-cuda-glib',
+                       extra_args: gir_extra_args,
+                       header: 'arrow-cuda-glib/arrow-cuda-glib.h',
+                       identifier_prefix: 'GArrowCUDA',
+                       includes: [
+                         'Arrow-1.0',
+                       ],
+                       install: true,
+                       namespace: 'ArrowCUDA',
+                       nsversion: api_version,
+                       sources: sources + c_headers,
+                       symbol_prefix: 'garrow_cuda')
+
+  if generate_vapi
+    arrow_cuda_glib_vapi = \
+      gnome.generate_vapi('arrow-cuda-glib',
+                          install: true,
+                          packages: [
+                            arrow_glib_vapi,
+                            'gio-2.0',
+                          ],
+                          sources: [arrow_cuda_glib_gir[0]])
+  endif
 endif
diff --git a/c_glib/arrow-dataset-glib/meson.build b/c_glib/arrow-dataset-glib/meson.build
index 1658d06574..463f7e15b1 100644
--- a/c_glib/arrow-dataset-glib/meson.build
+++ b/c_glib/arrow-dataset-glib/meson.build
@@ -85,20 +85,32 @@ pkgconfig.generate(libarrow_dataset_glib,
                    requires: ['arrow-glib', 'arrow-dataset'])
 
 if have_gi
-  gnome.generate_gir(libarrow_dataset_glib,
-                     dependencies: declare_dependency(sources: arrow_glib_gir),
-                     sources: sources + c_headers + enums,
-                     namespace: 'ArrowDataset',
-                     nsversion: api_version,
-                     identifier_prefix: 'GADataset',
-                     symbol_prefix: 'gadataset',
-                     export_packages: 'arrow-dataset-glib',
-                     includes: [
-                       'Arrow-1.0',
-                     ],
-                     install: true,
-                     extra_args: [
-                       '--warn-all',
-                       '--include-uninstalled=./arrow-glib/Arrow-1.0.gir',
-                     ])
+  dataset_glib_gir = \
+    gnome.generate_gir(libarrow_dataset_glib,
+                       dependencies: declare_dependency(sources: arrow_glib_gir),
+                       export_packages: 'arrow-dataset-glib',
+                       extra_args: [
+                         '--warn-all',
+                         '--include-uninstalled=./arrow-glib/Arrow-1.0.gir',
+                       ],
+                       header: 'arrow-dataset-glib/arrow-dataset-glib.h',
+                       identifier_prefix: 'GADataset',
+                       includes: [
+                         'Arrow-1.0',
+                       ],
+                       install: true,
+                       namespace: 'ArrowDataset',
+                       nsversion: api_version,
+                       sources: sources + c_headers + enums,
+                       symbol_prefix: 'gadataset')
+
+  if generate_vapi
+    gnome.generate_vapi('arrow-dataset-glib',
+                        install: true,
+                        packages: [
+                          arrow_glib_vapi,
+                          'gio-2.0',
+                        ],
+                        sources: [dataset_glib_gir[0]])
+  endif
 endif
diff --git a/c_glib/arrow-flight-glib/meson.build b/c_glib/arrow-flight-glib/meson.build
index c17415fee3..f962f5e461 100644
--- a/c_glib/arrow-flight-glib/meson.build
+++ b/c_glib/arrow-flight-glib/meson.build
@@ -63,20 +63,32 @@ pkgconfig.generate(libarrow_flight_glib,
                    requires: ['arrow-glib', 'arrow-flight'])
 
 if have_gi
-  gnome.generate_gir(libarrow_flight_glib,
-                     dependencies: declare_dependency(sources: arrow_glib_gir),
-                     sources: sources + c_headers,
-                     namespace: 'ArrowFlight',
-                     nsversion: api_version,
-                     identifier_prefix: 'GAFlight',
-                     symbol_prefix: 'gaflight',
-                     export_packages: 'arrow-flight-glib',
-                     includes: [
-                       'Arrow-1.0',
-                     ],
-                     install: true,
-                     extra_args: [
-                       '--warn-all',
-                       '--include-uninstalled=./arrow-glib/Arrow-1.0.gir',
-                     ])
+  flight_glib_gir = \
+    gnome.generate_gir(libarrow_flight_glib,
+                       dependencies: declare_dependency(sources: arrow_glib_gir),
+                       export_packages: 'arrow-flight-glib',
+                       extra_args: [
+                         '--warn-all',
+                         '--include-uninstalled=./arrow-glib/Arrow-1.0.gir',
+                       ],
+                       header: 'arrow-flight-glib/arrow-flight-glib.h',
+                       identifier_prefix: 'GAFlight',
+                       includes: [
+                         'Arrow-1.0',
+                       ],
+                       install: true,
+                       namespace: 'ArrowFlight',
+                       nsversion: api_version,
+                       sources: sources + c_headers,
+                       symbol_prefix: 'gaflight')
+
+  if generate_vapi
+    gnome.generate_vapi('arrow-flight-glib',
+                        install: true,
+                        packages: [
+                          arrow_glib_vapi,
+                          'gio-2.0',
+                        ],
+                        sources: [flight_glib_gir[0]])
+  endif
 endif
diff --git a/c_glib/arrow-glib/Arrow-1.0.metadata b/c_glib/arrow-glib/Arrow-1.0.metadata
new file mode 100644
index 0000000000..9c2c8c0184
--- /dev/null
+++ b/c_glib/arrow-glib/Arrow-1.0.metadata
@@ -0,0 +1,20 @@
+// 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.
+
+DecimalDataType.new skip
+// SourceNodeOptions.record_batch#property name="get_record_batch"
+SourceNodeOptions.record_batch#property skip
diff --git a/c_glib/arrow-glib/meson.build b/c_glib/arrow-glib/meson.build
index c87a3250d9..d5df698b60 100644
--- a/c_glib/arrow-glib/meson.build
+++ b/c_glib/arrow-glib/meson.build
@@ -266,18 +266,26 @@ endif
 
 if have_gi
   arrow_glib_gir = gnome.generate_gir(libarrow_glib,
-                                      sources: sources + c_headers + enums,
-                                      namespace: 'Arrow',
-                                      nsversion: api_version,
-                                      identifier_prefix: 'GArrow',
-                                      symbol_prefix: 'garrow',
                                       export_packages: 'arrow-glib',
+                                      extra_args: [
+                                        '--warn-all',
+                                      ],
+                                      header: 'arrow-glib/arrow-glib.h',
+                                      identifier_prefix: 'GArrow',
                                       includes: [
                                         'GObject-2.0',
                                         'Gio-2.0',
                                       ],
                                       install: true,
-                                      extra_args: [
-                                        '--warn-all',
-                                      ])
+                                      namespace: 'Arrow',
+                                      nsversion: api_version,
+                                      sources: sources + c_headers + enums,
+                                      symbol_prefix: 'garrow')
+
+  if generate_vapi
+    arrow_glib_vapi = gnome.generate_vapi('arrow-glib',
+                                          install: true,
+                                          packages: ['gio-2.0'],
+                                          sources: [arrow_glib_gir[0]])
+  endif
 endif
diff --git a/c_glib/example/README.md b/c_glib/example/README.md
index b69145d68f..8bd0242bd2 100644
--- a/c_glib/example/README.md
+++ b/c_glib/example/README.md
@@ -32,17 +32,17 @@ Here are example codes in this directory:
   * `build.c`: It shows how to create an array by array builder.
 
 <!---
-  * `write-batch.c`: It shows how to write Arrow array to file in batch
-    mode.
+  * `write-file.c`: It shows how to write Arrow array to file in file
+    format.
 -->
 
-  * `read-batch.c`: It shows how to read Arrow array from file in batch
-    mode.
+  * `read-file.c`: It shows how to read Arrow array from file in file
+    format.
 
 <!---
   * `write-stream.c`: It shows how to write Arrow array to file in
-    stream mode.
+    stream format.
 -->
 
   * `read-stream.c`: It shows how to read Arrow array from file in
-    stream mode.
+    stream format.
diff --git a/c_glib/example/lua/README.md b/c_glib/example/lua/README.md
index 7d388d46ac..0e62a610a2 100644
--- a/c_glib/example/lua/README.md
+++ b/c_glib/example/lua/README.md
@@ -28,23 +28,23 @@ Arrow GLib based bindings.
 
 Here are command lines to install LGI on Debian GNU/Linux and Ubuntu:
 
-```text
-% sudo apt install -y luarocks
-% sudo luarocks install lgi
+```console
+$ sudo apt install -y luarocks
+$ sudo luarocks install lgi
 ```
 
 ## Lua example codes
 
 Here are example codes in this directory:
 
-  * `write-batch.lua`: It shows how to write Arrow array to file in
-    batch mode.
+  * `write-file.lua`: It shows how to write Arrow array to file in
+    file format.
 
-  * `read-batch.lua`: It shows how to read Arrow array from file in
-    batch mode.
+  * `read-file.lua`: It shows how to read Arrow array from file in
+    file format.
 
   * `write-stream.lua`: It shows how to write Arrow array to file in
-    stream mode.
+    stream format.
 
   * `read-stream.lua`: It shows how to read Arrow array from file in
-    stream mode.
+    stream format.
diff --git a/c_glib/example/lua/meson.build b/c_glib/example/lua/meson.build
index 8fe3e5f238..4836001287 100644
--- a/c_glib/example/lua/meson.build
+++ b/c_glib/example/lua/meson.build
@@ -18,9 +18,9 @@
 # under the License.
 
 install_data('README.md',
-             'read-batch.lua',
+             'read-file.lua',
              'read-stream.lua',
-             'write-batch.lua',
+             'write-file.lua',
              'write-stream.lua',
              install_dir: join_paths(data_dir,
                                      meson.project_name(),
diff --git a/c_glib/example/lua/read-batch.lua b/c_glib/example/lua/read-file.lua
similarity index 100%
rename from c_glib/example/lua/read-batch.lua
rename to c_glib/example/lua/read-file.lua
diff --git a/c_glib/example/lua/write-batch.lua b/c_glib/example/lua/write-file.lua
similarity index 100%
rename from c_glib/example/lua/write-batch.lua
rename to c_glib/example/lua/write-file.lua
diff --git a/c_glib/example/meson.build b/c_glib/example/meson.build
index 9a9bef1bd4..b863ea7c9d 100644
--- a/c_glib/example/meson.build
+++ b/c_glib/example/meson.build
@@ -21,7 +21,7 @@ executable('build', 'build.c',
            dependencies: [arrow_glib])
 executable('extension-type', 'extension-type.c',
            dependencies: [arrow_glib])
-executable('read-batch', 'read-batch.c',
+executable('read-file', 'read-file.c',
            dependencies: [arrow_glib])
 executable('read-stream', 'read-stream.c',
            dependencies: [arrow_glib])
@@ -29,8 +29,9 @@ executable('read-stream', 'read-stream.c',
 install_data('README.md',
              'build.c',
              'extension-type.c',
-             'read-batch.c',
+             'read-file.c',
              'read-stream.c',
              install_dir: join_paths(data_dir, meson.project_name(), 'example'))
 
 subdir('lua')
+subdir('vala')
diff --git a/c_glib/example/read-batch.c b/c_glib/example/read-file.c
similarity index 98%
rename from c_glib/example/read-batch.c
rename to c_glib/example/read-file.c
index 273dc70ffa..8dae4290ec 100644
--- a/c_glib/example/read-batch.c
+++ b/c_glib/example/read-file.c
@@ -124,7 +124,7 @@ main(int argc, char **argv)
         record_batch =
           garrow_record_batch_file_reader_read_record_batch(reader, i, &error);
         if (!record_batch) {
-          g_print("failed to open file reader: %s\n", error->message);
+          g_print("failed to read %u-th record batch: %s\n", i, error->message);
           g_error_free(error);
           g_object_unref(reader);
           g_object_unref(input);
diff --git a/c_glib/example/lua/README.md b/c_glib/example/vala/README.md
similarity index 56%
copy from c_glib/example/lua/README.md
copy to c_glib/example/vala/README.md
index 7d388d46ac..8c11a54761 100644
--- a/c_glib/example/lua/README.md
+++ b/c_glib/example/vala/README.md
@@ -17,34 +17,32 @@
   under the License.
 -->
 
-# Arrow Lua example
+# Arrow Vala example
 
-There are Lua example codes in this directory.
+There are Vala example codes in this directory.
 
-## How to run
+## How to build
 
-All example codes use [LGI](https://github.com/pavouk/lgi) to use
-Arrow GLib based bindings.
+Here is a command line to build an example in this directory:
 
-Here are command lines to install LGI on Debian GNU/Linux and Ubuntu:
-
-```text
-% sudo apt install -y luarocks
-% sudo luarocks install lgi
+```console
+$ valac --pkg arrow-glib --pkg posix XXX.vala
 ```
 
-## Lua example codes
+## Vala example codes
 
 Here are example codes in this directory:
 
-  * `write-batch.lua`: It shows how to write Arrow array to file in
-    batch mode.
+  * `build.vala`: It shows how to create an array by array builder.
+
+  * `write-file.vala`: It shows how to write Arrow array to file in
+    file format.
 
-  * `read-batch.lua`: It shows how to read Arrow array from file in
-    batch mode.
+  * `read-file.vala`: It shows how to read Arrow array from file in
+    file format.
 
-  * `write-stream.lua`: It shows how to write Arrow array to file in
-    stream mode.
+  * `write-stream.vala`: It shows how to write Arrow array to file in
+    stream format.
 
-  * `read-stream.lua`: It shows how to read Arrow array from file in
-    stream mode.
+  * `read-stream.vala`: It shows how to read Arrow array from file in
+    stream format.
diff --git a/c_glib/example/vala/build.vala b/c_glib/example/vala/build.vala
new file mode 100644
index 0000000000..ee1e9acbd0
--- /dev/null
+++ b/c_glib/example/vala/build.vala
@@ -0,0 +1,47 @@
+// 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.
+
+int main (string[] args) {
+    var builder = new GArrow.Int32ArrayBuilder();
+    try {
+        builder.append_value(29);
+        builder.append_value(2929);
+        builder.append_value(292929);
+    } catch (Error error) {
+        stderr.printf("failed to append: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+
+    GArrow.Array array;
+    try {
+        array = builder.finish();
+    } catch (Error error) {
+        stderr.printf("failed to finish: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+
+    var int32_array = array as GArrow.Int32Array;
+    var n = array.get_length();
+    stdout.printf("length: %" + int64.FORMAT + "\n", n);
+    for (int64 i = 0; i < n; i++) {
+        var value = int32_array.get_value(i);
+        stdout.printf("array[%" + int64.FORMAT + "] = %d\n",
+                      i, value);
+    }
+
+    return Posix.EXIT_SUCCESS;
+}
diff --git a/c_glib/example/lua/meson.build b/c_glib/example/vala/meson.build
similarity index 51%
copy from c_glib/example/lua/meson.build
copy to c_glib/example/vala/meson.build
index 8fe3e5f238..42e40f692a 100644
--- a/c_glib/example/lua/meson.build
+++ b/c_glib/example/vala/meson.build
@@ -17,12 +17,38 @@
 # specific language governing permissions and limitations
 # under the License.
 
+if generate_vapi
+  vala_example_executable_kwargs = {
+    'c_args': [
+      '-I' + meson.build_root(),
+      '-I' + meson.source_root(),
+    ],
+    'dependencies': [
+      arrow_glib_vapi,
+      dependency('gio-2.0'),
+    ],
+    'vala_args': [
+      '--pkg', 'posix',
+    ],
+  }
+  executable('build', 'build.vala',
+             kwargs: vala_example_executable_kwargs)
+  executable('read-file', 'read-file.vala',
+             kwargs: vala_example_executable_kwargs)
+  executable('read-stream', 'read-stream.vala',
+             kwargs: vala_example_executable_kwargs)
+  executable('write-file', 'write-file.vala',
+             kwargs: vala_example_executable_kwargs)
+  executable('write-stream', 'write-stream.vala',
+             kwargs: vala_example_executable_kwargs)
+endif
+
 install_data('README.md',
-             'read-batch.lua',
-             'read-stream.lua',
-             'write-batch.lua',
-             'write-stream.lua',
+             'read-file.vala',
+             'read-stream.vala',
+             'write-file.vala',
+             'write-stream.vala',
              install_dir: join_paths(data_dir,
                                      meson.project_name(),
                                      'example',
-                                     'lua'))
+                                     'vala'))
diff --git a/c_glib/example/vala/read-file.vala b/c_glib/example/vala/read-file.vala
new file mode 100644
index 0000000000..a0a06275c4
--- /dev/null
+++ b/c_glib/example/vala/read-file.vala
@@ -0,0 +1,170 @@
+// 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.
+
+void print_array(GArrow.Array array) {
+    stdout.printf("[");
+    var n = array.get_length();
+
+    switch (array.get_value_type()) {
+    case GArrow.Type.UINT8:
+        var concrete_array = array as GArrow.UInt8Array;
+        for (var i = 0; i < n; i++) {
+            if (i > 0) {
+                stdout.printf(", ");
+            }
+            stdout.printf("%hhu", concrete_array.get_value(i));
+        }
+        break;
+    case GArrow.Type.UINT16:
+        var concrete_array = array as GArrow.UInt16Array;
+        for (var i = 0; i < n; i++) {
+            if (i > 0) {
+                stdout.printf(", ");
+            }
+            stdout.printf("%" + uint16.FORMAT, concrete_array.get_value(i));
+        }
+        break;
+    case GArrow.Type.UINT32:
+        var concrete_array = array as GArrow.UInt32Array;
+        for (var i = 0; i < n; i++) {
+            if (i > 0) {
+                stdout.printf(", ");
+            }
+            stdout.printf("%" + uint32.FORMAT, concrete_array.get_value(i));
+        }
+        break;
+    case GArrow.Type.UINT64:
+        var concrete_array = array as GArrow.UInt64Array;
+        for (var i = 0; i < n; i++) {
+            if (i > 0) {
+                stdout.printf(", ");
+            }
+            stdout.printf("%" + uint64.FORMAT, concrete_array.get_value(i));
+        }
+        break;
+    case GArrow.Type.INT8:
+        var concrete_array = array as GArrow.Int8Array;
+        for (var i = 0; i < n; i++) {
+            if (i > 0) {
+                stdout.printf(", ");
+            }
+            stdout.printf("%hhd", concrete_array.get_value(i));
+        }
+        break;
+    case GArrow.Type.INT16:
+        var concrete_array = array as GArrow.Int16Array;
+        for (var i = 0; i < n; i++) {
+            if (i > 0) {
+                stdout.printf(", ");
+            }
+            stdout.printf("%" + int16.FORMAT, concrete_array.get_value(i));
+        }
+        break;
+    case GArrow.Type.INT32:
+        var concrete_array = array as GArrow.Int32Array;
+        for (var i = 0; i < n; i++) {
+            if (i > 0) {
+                stdout.printf(", ");
+            }
+            stdout.printf("%" + int32.FORMAT, concrete_array.get_value(i));
+        }
+        break;
+    case GArrow.Type.INT64:
+        var concrete_array = array as GArrow.Int64Array;
+        for (var i = 0; i < n; i++) {
+            if (i > 0) {
+                stdout.printf(", ");
+            }
+            stdout.printf("%" + int64.FORMAT, concrete_array.get_value(i));
+        }
+        break;
+    case GArrow.Type.FLOAT:
+        var concrete_array = array as GArrow.FloatArray;
+        for (var i = 0; i < n; i++) {
+            if (i > 0) {
+                stdout.printf(", ");
+            }
+            stdout.printf("%g", concrete_array.get_value(i));
+        }
+        break;
+    case GArrow.Type.DOUBLE:
+        var concrete_array = array as GArrow.DoubleArray;
+        for (var i = 0; i < n; i++) {
+            if (i > 0) {
+                stdout.printf(", ");
+            }
+            stdout.printf("%g", concrete_array.get_value(i));
+        }
+        break;
+    default:
+        break;
+    }
+
+    stdout.printf("]\n");
+}
+
+void print_record_batch(GArrow.RecordBatch record_batch) {
+    var n_columns = record_batch.get_n_columns();
+    for (var nth_column = 0; nth_column < n_columns; nth_column++) {
+        stdout.printf("columns[%" + int64.FORMAT + "](%s): ",
+                      nth_column,
+                      record_batch.get_column_name(nth_column));
+        var array = record_batch.get_column_data(nth_column);
+        print_array(array);
+    }
+}
+
+int main (string[] args) {
+    var input_path = "/tmp/file.arrow";
+    if (args.length > 1) {
+        input_path = args[0];
+    }
+
+    GArrow.MemoryMappedInputStream input;
+    try {
+        input = new GArrow.MemoryMappedInputStream(input_path);
+    } catch (Error error) {
+        stderr.printf("failed to open file: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+
+    {
+        GArrow.RecordBatchFileReader reader;
+        try {
+            var seekable_input = input as GArrow.SeekableInputStream;
+            reader = new GArrow.RecordBatchFileReader(seekable_input);
+        } catch (Error error) {
+            stderr.printf("failed to open file reader: %s\n", error.message);
+            return Posix.EXIT_FAILURE;
+        }
+
+        var n = reader.get_n_record_batches();
+        for (var i = 0; i < n; i++) {
+            GArrow.RecordBatch record_batch;
+            try {
+                record_batch = reader.read_record_batch(i);
+            } catch (Error error) {
+                stderr.printf("failed to read %u-th record batch: %s\n",
+                              i, error.message);
+                return Posix.EXIT_FAILURE;
+            }
+            print_record_batch(record_batch);
+        }
+    }
+
+    return Posix.EXIT_SUCCESS;
+}
diff --git a/c_glib/example/vala/read-stream.vala b/c_glib/example/vala/read-stream.vala
new file mode 100644
index 0000000000..c58dc84893
--- /dev/null
+++ b/c_glib/example/vala/read-stream.vala
@@ -0,0 +1,172 @@
+// 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.
+
+void print_array(GArrow.Array array) {
+    stdout.printf("[");
+    var n = array.get_length();
+
+    switch (array.get_value_type()) {
+    case GArrow.Type.UINT8:
+        var concrete_array = array as GArrow.UInt8Array;
+        for (var i = 0; i < n; i++) {
+            if (i > 0) {
+                stdout.printf(", ");
+            }
+            stdout.printf("%hhu", concrete_array.get_value(i));
+        }
+        break;
+    case GArrow.Type.UINT16:
+        var concrete_array = array as GArrow.UInt16Array;
+        for (var i = 0; i < n; i++) {
+            if (i > 0) {
+                stdout.printf(", ");
+            }
+            stdout.printf("%" + uint16.FORMAT, concrete_array.get_value(i));
+        }
+        break;
+    case GArrow.Type.UINT32:
+        var concrete_array = array as GArrow.UInt32Array;
+        for (var i = 0; i < n; i++) {
+            if (i > 0) {
+                stdout.printf(", ");
+            }
+            stdout.printf("%" + uint32.FORMAT, concrete_array.get_value(i));
+        }
+        break;
+    case GArrow.Type.UINT64:
+        var concrete_array = array as GArrow.UInt64Array;
+        for (var i = 0; i < n; i++) {
+            if (i > 0) {
+                stdout.printf(", ");
+            }
+            stdout.printf("%" + uint64.FORMAT, concrete_array.get_value(i));
+        }
+        break;
+    case GArrow.Type.INT8:
+        var concrete_array = array as GArrow.Int8Array;
+        for (var i = 0; i < n; i++) {
+            if (i > 0) {
+                stdout.printf(", ");
+            }
+            stdout.printf("%hhd", concrete_array.get_value(i));
+        }
+        break;
+    case GArrow.Type.INT16:
+        var concrete_array = array as GArrow.Int16Array;
+        for (var i = 0; i < n; i++) {
+            if (i > 0) {
+                stdout.printf(", ");
+            }
+            stdout.printf("%" + int16.FORMAT, concrete_array.get_value(i));
+        }
+        break;
+    case GArrow.Type.INT32:
+        var concrete_array = array as GArrow.Int32Array;
+        for (var i = 0; i < n; i++) {
+            if (i > 0) {
+                stdout.printf(", ");
+            }
+            stdout.printf("%" + int32.FORMAT, concrete_array.get_value(i));
+        }
+        break;
+    case GArrow.Type.INT64:
+        var concrete_array = array as GArrow.Int64Array;
+        for (var i = 0; i < n; i++) {
+            if (i > 0) {
+                stdout.printf(", ");
+            }
+            stdout.printf("%" + int64.FORMAT, concrete_array.get_value(i));
+        }
+        break;
+    case GArrow.Type.FLOAT:
+        var concrete_array = array as GArrow.FloatArray;
+        for (var i = 0; i < n; i++) {
+            if (i > 0) {
+                stdout.printf(", ");
+            }
+            stdout.printf("%g", concrete_array.get_value(i));
+        }
+        break;
+    case GArrow.Type.DOUBLE:
+        var concrete_array = array as GArrow.DoubleArray;
+        for (var i = 0; i < n; i++) {
+            if (i > 0) {
+                stdout.printf(", ");
+            }
+            stdout.printf("%g", concrete_array.get_value(i));
+        }
+        break;
+    default:
+        break;
+    }
+
+    stdout.printf("]\n");
+}
+
+void print_record_batch(GArrow.RecordBatch record_batch) {
+    var n_columns = record_batch.get_n_columns();
+    for (var nth_column = 0; nth_column < n_columns; nth_column++) {
+        stdout.printf("columns[%" + int64.FORMAT + "](%s): ",
+                      nth_column,
+                      record_batch.get_column_name(nth_column));
+        var array = record_batch.get_column_data(nth_column);
+        print_array(array);
+    }
+}
+
+int main (string[] args) {
+    var input_path = "/tmp/stream.arrow";
+    if (args.length > 1) {
+        input_path = args[0];
+    }
+
+    GArrow.MemoryMappedInputStream input;
+    try {
+        input = new GArrow.MemoryMappedInputStream(input_path);
+    } catch (Error error) {
+        stderr.printf("failed to open file: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+
+    {
+        GArrow.RecordBatchStreamReader reader;
+        try {
+            var seekable_input = input as GArrow.SeekableInputStream;
+            reader = new GArrow.RecordBatchStreamReader(seekable_input);
+        } catch (Error error) {
+            stderr.printf("failed to open stream reader: %s\n", error.message);
+            return Posix.EXIT_FAILURE;
+        }
+
+        while (true) {
+            GArrow.RecordBatch record_batch;
+            try {
+                record_batch = reader.read_next();
+            } catch (Error error) {
+                stderr.printf("failed to read the next record batch: %s\n",
+                              error.message);
+                return Posix.EXIT_FAILURE;
+            }
+            if (record_batch == null) {
+                break;
+            }
+            print_record_batch(record_batch);
+        }
+    }
+
+    return Posix.EXIT_SUCCESS;
+}
diff --git a/c_glib/example/vala/write-file.vala b/c_glib/example/vala/write-file.vala
new file mode 100644
index 0000000000..2d224b46b8
--- /dev/null
+++ b/c_glib/example/vala/write-file.vala
@@ -0,0 +1,153 @@
+// 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.
+
+int main (string[] args) {
+    var output_path = "/tmp/file.arrow";
+    if (args.length > 1) {
+        output_path = args[0];
+    }
+
+    var fields = new GLib.List<GArrow.Field>();
+    fields.append(new GArrow.Field("uint8", new GArrow.UInt8DataType()));
+    fields.append(new GArrow.Field("uint16", new GArrow.UInt16DataType()));
+    fields.append(new GArrow.Field("uint32", new GArrow.UInt32DataType()));
+    fields.append(new GArrow.Field("uint64", new GArrow.UInt64DataType()));
+    fields.append(new GArrow.Field("int8", new GArrow.Int8DataType()));
+    fields.append(new GArrow.Field("int16", new GArrow.Int16DataType()));
+    fields.append(new GArrow.Field("int32", new GArrow.Int32DataType()));
+    fields.append(new GArrow.Field("int64", new GArrow.Int64DataType()));
+    fields.append(new GArrow.Field("float", new GArrow.FloatDataType()));
+    fields.append(new GArrow.Field("double", new GArrow.DoubleDataType()));
+    var schema = new GArrow.Schema(fields);
+
+    GArrow.FileOutputStream output;
+    try {
+        output = new GArrow.FileOutputStream(output_path, false);
+    } catch (Error error) {
+        stderr.printf("failed to open output path: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+
+    GArrow.RecordBatchFileWriter writer;
+    try {
+        writer = new GArrow.RecordBatchFileWriter(output, schema);
+    } catch (Error error) {
+        stderr.printf("failed to create writer: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+
+    var n_rows = 4;
+    var columns = new GLib.List<GArrow.Array>();
+    try {
+        var builder = new GArrow.UInt8ArrayBuilder();
+        builder.append_values({1, 2, 4, 8}, null);
+        columns.append(builder.finish());
+    } catch (Error error) {
+        stderr.printf("failed to build an array: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+    try {
+        var builder = new GArrow.UInt16ArrayBuilder();
+        builder.append_values({1, 2, 4, 8}, null);
+        columns.append(builder.finish());
+    } catch (Error error) {
+        stderr.printf("failed to build an array: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+    try {
+        var builder = new GArrow.UInt32ArrayBuilder();
+        builder.append_values({1, 2, 4, 8}, null);
+        columns.append(builder.finish());
+    } catch (Error error) {
+        stderr.printf("failed to build an array: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+    try {
+        var builder = new GArrow.UInt64ArrayBuilder();
+        builder.append_values({1, 2, 4, 8}, null);
+        columns.append(builder.finish());
+    } catch (Error error) {
+        stderr.printf("failed to build an array: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+    try {
+        var builder = new GArrow.Int8ArrayBuilder();
+        builder.append_values({1, -2, 4, -8}, null);
+        columns.append(builder.finish());
+    } catch (Error error) {
+        stderr.printf("failed to build an array: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+    try {
+        var builder = new GArrow.Int16ArrayBuilder();
+        builder.append_values({1, -2, 4, -8}, null);
+        columns.append(builder.finish());
+    } catch (Error error) {
+        stderr.printf("failed to build an array: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+    try {
+        var builder = new GArrow.Int32ArrayBuilder();
+        builder.append_values({1, -2, 4, -8}, null);
+        columns.append(builder.finish());
+    } catch (Error error) {
+        stderr.printf("failed to build an array: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+    try {
+        var builder = new GArrow.Int64ArrayBuilder();
+        builder.append_values({1, -2, 4, -8}, null);
+        columns.append(builder.finish());
+    } catch (Error error) {
+        stderr.printf("failed to build an array: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+    try {
+        var builder = new GArrow.FloatArrayBuilder();
+        builder.append_values({1.1f, -2.2f, 4.4f, -8.8f}, null);
+        columns.append(builder.finish());
+    } catch (Error error) {
+        stderr.printf("failed to build an array: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+    try {
+        var builder = new GArrow.DoubleArrayBuilder();
+        builder.append_values({1.1, -2.2, 4.4, -8.8}, null);
+        columns.append(builder.finish());
+    } catch (Error error) {
+        stderr.printf("failed to build an array: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+
+    try {
+        var record_batch = new GArrow.RecordBatch(schema, n_rows, columns);
+        writer.write_record_batch(record_batch);
+    } catch (Error error) {
+        stderr.printf("failed to build a record batch: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+
+    try {
+        writer.close();
+        output.close();
+    } catch (Error error) {
+        stderr.printf("failed to close: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+
+    return Posix.EXIT_SUCCESS;
+}
diff --git a/c_glib/example/vala/write-stream.vala b/c_glib/example/vala/write-stream.vala
new file mode 100644
index 0000000000..29758e5ab7
--- /dev/null
+++ b/c_glib/example/vala/write-stream.vala
@@ -0,0 +1,153 @@
+// 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.
+
+int main (string[] args) {
+    var output_path = "/tmp/stream.arrow";
+    if (args.length > 1) {
+        output_path = args[0];
+    }
+
+    var fields = new GLib.List<GArrow.Field>();
+    fields.append(new GArrow.Field("uint8", new GArrow.UInt8DataType()));
+    fields.append(new GArrow.Field("uint16", new GArrow.UInt16DataType()));
+    fields.append(new GArrow.Field("uint32", new GArrow.UInt32DataType()));
+    fields.append(new GArrow.Field("uint64", new GArrow.UInt64DataType()));
+    fields.append(new GArrow.Field("int8", new GArrow.Int8DataType()));
+    fields.append(new GArrow.Field("int16", new GArrow.Int16DataType()));
+    fields.append(new GArrow.Field("int32", new GArrow.Int32DataType()));
+    fields.append(new GArrow.Field("int64", new GArrow.Int64DataType()));
+    fields.append(new GArrow.Field("float", new GArrow.FloatDataType()));
+    fields.append(new GArrow.Field("double", new GArrow.DoubleDataType()));
+    var schema = new GArrow.Schema(fields);
+
+    GArrow.FileOutputStream output;
+    try {
+        output = new GArrow.FileOutputStream(output_path, false);
+    } catch (Error error) {
+        stderr.printf("failed to open output path: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+
+    GArrow.RecordBatchStreamWriter writer;
+    try {
+        writer = new GArrow.RecordBatchStreamWriter(output, schema);
+    } catch (Error error) {
+        stderr.printf("failed to create writer: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+
+    var n_rows = 4;
+    var columns = new GLib.List<GArrow.Array>();
+    try {
+        var builder = new GArrow.UInt8ArrayBuilder();
+        builder.append_values({1, 2, 4, 8}, null);
+        columns.append(builder.finish());
+    } catch (Error error) {
+        stderr.printf("failed to build an array: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+    try {
+        var builder = new GArrow.UInt16ArrayBuilder();
+        builder.append_values({1, 2, 4, 8}, null);
+        columns.append(builder.finish());
+    } catch (Error error) {
+        stderr.printf("failed to build an array: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+    try {
+        var builder = new GArrow.UInt32ArrayBuilder();
+        builder.append_values({1, 2, 4, 8}, null);
+        columns.append(builder.finish());
+    } catch (Error error) {
+        stderr.printf("failed to build an array: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+    try {
+        var builder = new GArrow.UInt64ArrayBuilder();
+        builder.append_values({1, 2, 4, 8}, null);
+        columns.append(builder.finish());
+    } catch (Error error) {
+        stderr.printf("failed to build an array: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+    try {
+        var builder = new GArrow.Int8ArrayBuilder();
+        builder.append_values({1, -2, 4, -8}, null);
+        columns.append(builder.finish());
+    } catch (Error error) {
+        stderr.printf("failed to build an array: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+    try {
+        var builder = new GArrow.Int16ArrayBuilder();
+        builder.append_values({1, -2, 4, -8}, null);
+        columns.append(builder.finish());
+    } catch (Error error) {
+        stderr.printf("failed to build an array: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+    try {
+        var builder = new GArrow.Int32ArrayBuilder();
+        builder.append_values({1, -2, 4, -8}, null);
+        columns.append(builder.finish());
+    } catch (Error error) {
+        stderr.printf("failed to build an array: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+    try {
+        var builder = new GArrow.Int64ArrayBuilder();
+        builder.append_values({1, -2, 4, -8}, null);
+        columns.append(builder.finish());
+    } catch (Error error) {
+        stderr.printf("failed to build an array: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+    try {
+        var builder = new GArrow.FloatArrayBuilder();
+        builder.append_values({1.1f, -2.2f, 4.4f, -8.8f}, null);
+        columns.append(builder.finish());
+    } catch (Error error) {
+        stderr.printf("failed to build an array: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+    try {
+        var builder = new GArrow.DoubleArrayBuilder();
+        builder.append_values({1.1, -2.2, 4.4, -8.8}, null);
+        columns.append(builder.finish());
+    } catch (Error error) {
+        stderr.printf("failed to build an array: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+
+    try {
+        var record_batch = new GArrow.RecordBatch(schema, n_rows, columns);
+        writer.write_record_batch(record_batch);
+    } catch (Error error) {
+        stderr.printf("failed to build a record batch: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+
+    try {
+        writer.close();
+        output.close();
+    } catch (Error error) {
+        stderr.printf("failed to close: %s\n", error.message);
+        return Posix.EXIT_FAILURE;
+    }
+
+    return Posix.EXIT_SUCCESS;
+}
diff --git a/c_glib/gandiva-glib/meson.build b/c_glib/gandiva-glib/meson.build
index 8d811693f2..1695d15a98 100644
--- a/c_glib/gandiva-glib/meson.build
+++ b/c_glib/gandiva-glib/meson.build
@@ -101,20 +101,32 @@ pkgconfig.generate(libgandiva_glib,
                    requires: ['gandiva', 'arrow-glib'])
 
 if have_gi
-  gnome.generate_gir(libgandiva_glib,
-                     dependencies: declare_dependency(sources: arrow_glib_gir),
-                     sources: sources + c_headers + enums,
-                     namespace: 'Gandiva',
-                     nsversion: api_version,
-                     identifier_prefix: 'GGandiva',
-                     symbol_prefix: 'ggandiva',
-                     export_packages: 'gandiva-glib',
-                     includes: [
-                       'Arrow-1.0'
-                     ],
-                     install: true,
-                     extra_args: [
-                       '--warn-all',
-                       '--include-uninstalled=./arrow-glib/Arrow-1.0.gir',
-                     ])
+  gandiva_glib_gir = \
+    gnome.generate_gir(libgandiva_glib,
+                       dependencies: declare_dependency(sources: arrow_glib_gir),
+                       export_packages: 'gandiva-glib',
+                       extra_args: [
+                         '--warn-all',
+                         '--include-uninstalled=./arrow-glib/Arrow-1.0.gir',
+                       ],
+                       header: 'gandiva-glib/gandiva-glib.h',
+                       identifier_prefix: 'GGandiva',
+                       includes: [
+                         'Arrow-1.0'
+                       ],
+                       install: true,
+                       namespace: 'Gandiva',
+                       nsversion: api_version,
+                       sources: sources + c_headers + enums,
+                       symbol_prefix: 'ggandiva')
+
+  if generate_vapi
+    gnome.generate_vapi('gandiva-glib',
+                        install: true,
+                        packages: [
+                          arrow_glib_vapi,
+                          'gio-2.0',
+                        ],
+                        sources: [gandiva_glib_gir[0]])
+  endif
 endif
diff --git a/c_glib/meson.build b/c_glib/meson.build
index 58a7680dc8..81352463ae 100644
--- a/c_glib/meson.build
+++ b/c_glib/meson.build
@@ -52,6 +52,10 @@ base_include_directories = [
 ]
 
 have_gi = dependency('gobject-introspection-1.0', required: false).found()
+generate_vapi = have_gi and get_option('vala')
+if generate_vapi
+  add_languages('vala')
+endif
 
 arrow_cpp_build_dir = get_option('arrow_cpp_build_dir')
 arrow_cpp_build_type = get_option('arrow_cpp_build_type')
diff --git a/c_glib/meson_options.txt b/c_glib/meson_options.txt
index 861b9bccdd..1be131b5ca 100644
--- a/c_glib/meson_options.txt
+++ b/c_glib/meson_options.txt
@@ -31,3 +31,8 @@ option('gtk_doc',
        type: 'boolean',
        value: false,
        description: 'Build document by GTK-Doc')
+
+option('vala',
+       type: 'boolean',
+       value: false,
+       description: 'Build Vala API')
diff --git a/c_glib/parquet-glib/meson.build b/c_glib/parquet-glib/meson.build
index cb453749a9..e3b5d3e986 100644
--- a/c_glib/parquet-glib/meson.build
+++ b/c_glib/parquet-glib/meson.build
@@ -70,20 +70,32 @@ pkgconfig.generate(libparquet_glib,
                    requires: ['parquet', 'arrow-glib'])
 
 if have_gi
-  gnome.generate_gir(libparquet_glib,
-                     dependencies: declare_dependency(sources: arrow_glib_gir),
-                     sources: sources + c_headers,
-                     namespace: 'Parquet',
-                     nsversion: api_version,
-                     identifier_prefix: 'GParquet',
-                     symbol_prefix: 'gparquet',
-                     export_packages: 'parquet-glib',
-                     includes: [
-                       'Arrow-1.0',
-                     ],
-                     install: true,
-                     extra_args: [
-                       '--warn-all',
-                       '--include-uninstalled=./arrow-glib/Arrow-1.0.gir',
-                     ])
+  parquet_glib_gir = \
+    gnome.generate_gir(libparquet_glib,
+                       dependencies: declare_dependency(sources: arrow_glib_gir),
+                       export_packages: 'parquet-glib',
+                       extra_args: [
+                         '--warn-all',
+                         '--include-uninstalled=./arrow-glib/Arrow-1.0.gir',
+                       ],
+                       header: 'parquet-glib/parquet-glib.h',
+                       identifier_prefix: 'GParquet',
+                       includes: [
+                         'Arrow-1.0',
+                       ],
+                       install: true,
+                       namespace: 'Parquet',
+                       nsversion: api_version,
+                       sources: sources + c_headers,
+                       symbol_prefix: 'gparquet')
+
+  if generate_vapi
+    gnome.generate_vapi('parquet-glib',
+                        install: true,
+                        packages: [
+                          arrow_glib_vapi,
+                          'gio-2.0',
+                        ],
+                        sources: [parquet_glib_gir[0]])
+  endif
 endif
diff --git a/c_glib/plasma-glib/meson.build b/c_glib/plasma-glib/meson.build
index 61ce69d1e3..3742c4927d 100644
--- a/c_glib/plasma-glib/meson.build
+++ b/c_glib/plasma-glib/meson.build
@@ -62,6 +62,12 @@ if have_gi
     '--warn-all',
     '--include-uninstalled=./arrow-glib/Arrow-1.0.gir',
   ]
+  if generate_vapi
+    vapi_packages = [
+      arrow_glib_vapi,
+      'gio-2.0',
+    ]
+  endif
 endif
 if arrow_cuda.found()
   dependencies += [arrow_cuda_glib]
@@ -71,6 +77,9 @@ if arrow_cuda.found()
     gir_dependencies += [declare_dependency(sources: arrow_cuda_glib_gir)]
     gir_includes += ['ArrowCUDA-1.0']
     gir_extra_args += ['--include-uninstalled=./arrow-cuda-glib/ArrowCUDA-1.0.gir']
+    if generate_vapi
+      vapi_packages += [arrow_cuda_glib_vapi]
+    endif
   endif
 endif
 libplasma_glib = library('plasma-glib',
@@ -93,15 +102,24 @@ pkgconfig.generate(libplasma_glib,
                    requires: pkg_config_requires)
 
 if have_gi
-  gnome.generate_gir(libplasma_glib,
-                     dependencies: gir_dependencies,
-                     sources: sources + c_headers,
-                     namespace: 'Plasma',
-                     nsversion: api_version,
-                     identifier_prefix: 'GPlasma',
-                     symbol_prefix: 'gplasma',
-                     export_packages: 'plasma-glib',
-                     includes: gir_includes,
-                     install: true,
-                     extra_args: gir_extra_args)
+  plasma_glib_gir = \
+    gnome.generate_gir(libplasma_glib,
+                       dependencies: gir_dependencies,
+                       export_packages: 'plasma-glib',
+                       extra_args: gir_extra_args,
+                       header: 'plasma-glib/plasma-glib.h',
+                       identifier_prefix: 'GPlasma',
+                       includes: gir_includes,
+                       install: true,
+                       namespace: 'Plasma',
+                       nsversion: api_version,
+                       sources: sources + c_headers,
+                       symbol_prefix: 'gplasma')
+
+  if generate_vapi
+    gnome.generate_vapi('plasma-glib',
+                        install: true,
+                        packages: vapi_packages,
+                        sources: plasma_glib_gir[0])
+  endif
 endif
diff --git a/ci/docker/linux-apt-c-glib.dockerfile b/ci/docker/linux-apt-c-glib.dockerfile
index 12c6e23a00..dfa1b190c9 100644
--- a/ci/docker/linux-apt-c-glib.dockerfile
+++ b/ci/docker/linux-apt-c-glib.dockerfile
@@ -20,19 +20,17 @@ FROM ${base}
 
 RUN apt-get update -y -q && \
     apt-get install -y -q \
-        python3 \
-        python3-pip \
         gtk-doc-tools \
         libgirepository1.0-dev \
         libglib2.0-doc \
         lsb-release \
         luarocks \
+        ninja-build \
         pkg-config \
-        ruby-dev && \
-    if [ "$(lsb_release --codename --short)" = "xenial" ]; then \
-      apt-get install -y -q --no-install-recommends -t xenial-backports \
-        ninja-build; \
-    fi && \
+        python3 \
+        python3-pip \
+        ruby-dev \
+        valac && \
     apt-get clean && \
     rm -rf /var/lib/apt/lists/*
 
diff --git a/ci/docker/linux-apt-docs.dockerfile b/ci/docker/linux-apt-docs.dockerfile
index 52c47c35d5..0ef1231321 100644
--- a/ci/docker/linux-apt-docs.dockerfile
+++ b/ci/docker/linux-apt-docs.dockerfile
@@ -93,11 +93,12 @@ COPY r/DESCRIPTION /arrow/r/
 RUN /arrow/ci/scripts/r_deps.sh /arrow && \
     R -e "install.packages('pkgdown')"
 
-ENV ARROW_FLIGHT=ON \
-    ARROW_PYTHON=ON \
-    ARROW_S3=ON \
-    ARROW_BUILD_STATIC=OFF \
+ENV ARROW_BUILD_STATIC=OFF \
     ARROW_BUILD_TESTS=OFF \
     ARROW_BUILD_UTILITIES=OFF \
+    ARROW_FLIGHT=ON \
+    ARROW_GLIB_VALA=false \
+    ARROW_PYTHON=ON \
+    ARROW_S3=ON \
     ARROW_USE_GLOG=OFF \
     CMAKE_UNITY_BUILD=ON
diff --git a/ci/scripts/c_glib_build.sh b/ci/scripts/c_glib_build.sh
index 8efa0ae96b..a2fbfec4b3 100755
--- a/ci/scripts/c_glib_build.sh
+++ b/ci/scripts/c_glib_build.sh
@@ -24,6 +24,7 @@ build_dir=${2}/c_glib
 build_root=${2}
 
 : ${ARROW_GLIB_WERROR:=false}
+: ${ARROW_GLIB_VALA:=true}
 : ${BUILD_DOCS_C_GLIB:=OFF}
 with_gtk_doc=$([ "${BUILD_DOCS_C_GLIB}" == "ON" ] && echo "true" || echo "false")
 
@@ -38,6 +39,7 @@ mkdir -p ${build_dir}
 meson --prefix=$ARROW_HOME \
       --libdir=lib \
       -Dgtk_doc=${with_gtk_doc} \
+      -Dvala=${ARROW_GLIB_VALA} \
       -Dwerror=${ARROW_GLIB_WERROR} \
       ${build_dir} \
       ${source_dir}
diff --git a/ci/scripts/c_glib_test.sh b/ci/scripts/c_glib_test.sh
index cb576136d4..9f0e8e7c4d 100755
--- a/ci/scripts/c_glib_test.sh
+++ b/ci/scripts/c_glib_test.sh
@@ -22,6 +22,8 @@ set -ex
 source_dir=${1}/c_glib
 build_dir=${2}/c_glib
 
+: ${ARROW_GLIB_VALA:=true}
+
 export LD_LIBRARY_PATH=${ARROW_HOME}/lib:${LD_LIBRARY_PATH}
 export PKG_CONFIG_PATH=${ARROW_HOME}/lib/pkgconfig
 export GI_TYPELIB_PATH=${ARROW_HOME}/lib/girepository-1.0
@@ -34,18 +36,22 @@ pushd ${source_dir}
 ruby test/run-test.rb
 
 if [[ "$(uname -s)" == "Linux" ]]; then
-    # TODO(kszucs): on osx it fails to load 'lgi.corelgilua51' despite that lgi
-    # was installed by luarocks
-    pushd example/lua
-    lua write-batch.lua
-    lua read-batch.lua
-    lua write-stream.lua
-    lua read-stream.lua
-    popd
+  # TODO(kszucs): on osx it fails to load 'lgi.corelgilua51' despite that lgi
+  # was installed by luarocks
+  pushd example/lua
+  lua write-file.lua
+  lua read-file.lua
+  lua write-stream.lua
+  lua read-stream.lua
+  popd
 fi
 
 popd
 
 pushd ${build_dir}
+example/build
 example/extension-type
+if [ "${ARROW_GLIB_VALA}" = "true" ]; then
+  example/vala/build
+fi
 popd
diff --git a/ci/scripts/msys2_setup.sh b/ci/scripts/msys2_setup.sh
index b7401546ff..d7e39450b4 100755
--- a/ci/scripts/msys2_setup.sh
+++ b/ci/scripts/msys2_setup.sh
@@ -56,6 +56,7 @@ case "${target}" in
     packages+=(${MINGW_PACKAGE_PREFIX}-gobject-introspection)
     packages+=(${MINGW_PACKAGE_PREFIX}-gtk-doc)
     packages+=(${MINGW_PACKAGE_PREFIX}-meson)
+    packages+=(${MINGW_PACKAGE_PREFIX}-vala)
     ;;
 esac
 
diff --git a/dev/release/setup-rhel-rebuilds.sh b/dev/release/setup-rhel-rebuilds.sh
index cb9cf0a6c0..1fe3ba47dc 100755
--- a/dev/release/setup-rhel-rebuilds.sh
+++ b/dev/release/setup-rhel-rebuilds.sh
@@ -46,6 +46,7 @@ dnf -y install \
   python38-pip \
   ruby-devel \
   sqlite-devel \
+  vala-devel \
   wget \
   which
 npm install -g yarn
diff --git a/dev/release/verify-apt.sh b/dev/release/verify-apt.sh
index 184a8f5a94..ab6b3151e2 100755
--- a/dev/release/verify-apt.sh
+++ b/dev/release/verify-apt.sh
@@ -61,7 +61,6 @@ case "${TYPE}" in
     ;;
 esac
 
-have_flight=yes
 have_plasma=yes
 have_python=yes
 workaround_missing_packages=()
@@ -147,7 +146,7 @@ required_packages+=(pkg-config)
 required_packages+=(${workaround_missing_packages[@]})
 ${APT_INSTALL} ${required_packages[@]}
 mkdir -p build
-cp -a /arrow/cpp/examples/minimal_build build
+cp -a /arrow/cpp/examples/minimal_build build/
 pushd build/minimal_build
 cmake .
 make -j$(nproc)
@@ -162,19 +161,32 @@ echo "::group::Test Apache Arrow GLib"
 ${APT_INSTALL} libarrow-glib-dev=${package_version}
 ${APT_INSTALL} libarrow-glib-doc=${package_version}
 
+${APT_INSTALL} valac
+cp -a /arrow/c_glib/example/vala build/
+pushd build/vala
+valac --pkg arrow-glib --pkg posix build.vala
+./build
+popd
+
+
 ${APT_INSTALL} ruby-dev rubygems-integration
 gem install gobject-introspection
 ruby -r gi -e "p GI.load('Arrow')"
 echo "::endgroup::"
 
 
-if [ "${have_flight}" = "yes" ]; then
-  echo "::group::Test Apache Arrow Flight"
-  ${APT_INSTALL} libarrow-flight-glib-dev=${package_version}
-  ${APT_INSTALL} libarrow-flight-glib-doc=${package_version}
-  ruby -r gi -e "p GI.load('ArrowFlight')"
-  echo "::endgroup::"
-fi
+echo "::group::Test Apache Arrow Dataset"
+${APT_INSTALL} libarrow-dataset-glib-dev=${package_version}
+${APT_INSTALL} libarrow-dataset-glib-doc=${package_version}
+ruby -r gi -e "p GI.load('ArrowDataset')"
+echo "::endgroup::"
+
+
+echo "::group::Test Apache Arrow Flight"
+${APT_INSTALL} libarrow-flight-glib-dev=${package_version}
+${APT_INSTALL} libarrow-flight-glib-doc=${package_version}
+ruby -r gi -e "p GI.load('ArrowFlight')"
+echo "::endgroup::"
 
 
 if [ "${have_python}" = "yes" ]; then
@@ -206,10 +218,3 @@ ${APT_INSTALL} libparquet-glib-dev=${package_version}
 ${APT_INSTALL} libparquet-glib-doc=${package_version}
 ruby -r gi -e "p GI.load('Parquet')"
 echo "::endgroup::"
-
-
-echo "::group::Test Apache Arrow Dataset"
-${APT_INSTALL} libarrow-dataset-glib-dev=${package_version}
-${APT_INSTALL} libarrow-dataset-glib-doc=${package_version}
-ruby -r gi -e "p GI.load('ArrowDataset')"
-echo "::endgroup::"
diff --git a/dev/release/verify-release-candidate.sh b/dev/release/verify-release-candidate.sh
index 92f4da4aac..e9bc6b02b2 100755
--- a/dev/release/verify-release-candidate.sh
+++ b/dev/release/verify-release-candidate.sh
@@ -243,6 +243,7 @@ test_yum() {
     esac
     if ! docker run \
            --rm \
+           --security-opt="seccomp=unconfined" \
            --volume "${SOURCE_DIR}"/../..:/arrow:delegated \
            "${target}" \
            /arrow/dev/release/verify-yum.sh \
@@ -258,6 +259,7 @@ test_yum() {
       if ! docker run \
              --platform linux/arm64 \
              --rm \
+             --security-opt="seccomp=unconfined" \
              --volume "${SOURCE_DIR}"/../..:/arrow:delegated \
              "${target}" \
              /arrow/dev/release/verify-yum.sh \
diff --git a/dev/release/verify-yum.sh b/dev/release/verify-yum.sh
index 17c36e4be9..caed5e37b0 100755
--- a/dev/release/verify-yum.sh
+++ b/dev/release/verify-yum.sh
@@ -53,6 +53,8 @@ have_parquet=yes
 have_python=yes
 install_command="dnf install -y --enablerepo=powertools"
 
+echo "::group::Prepare repository"
+
 case "${distribution}-${distribution_version}" in
   almalinux-*)
     distribution_prefix="almalinux"
@@ -152,6 +154,10 @@ else
   esac
 fi
 
+echo "::endgroup::"
+
+
+echo "::group::Test Apache Arrow C++"
 ${install_command} --enablerepo=epel arrow-devel-${package_version}
 ${install_command} \
   ${cmake_package} \
@@ -161,7 +167,7 @@ ${install_command} \
   make \
   pkg-config
 mkdir -p build
-cp -a /arrow/cpp/examples/minimal_build build
+cp -a /arrow/cpp/examples/minimal_build build/
 pushd build/minimal_build
 ${cmake_command} .
 make -j$(nproc)
@@ -169,42 +175,62 @@ make -j$(nproc)
 c++ -std=c++11 -o arrow-example example.cc $(pkg-config --cflags --libs arrow)
 ./arrow-example
 popd
+echo "::endgroup::"
 
 if [ "${have_glib}" = "yes" ]; then
+  echo "::group::Test Apache Arrow GLib"
   ${install_command} --enablerepo=epel arrow-glib-devel-${package_version}
   ${install_command} --enablerepo=epel arrow-glib-doc-${package_version}
+
+  ${install_command} vala
+  cp -a /arrow/c_glib/example/vala build/
+  pushd build/vala
+  valac --pkg arrow-glib --pkg posix build.vala
+  ./build
+  popd
+  echo "::endgroup::"
+fi
+
+if [ "${have_flight}" = "yes" ]; then
+  echo "::group::Test Apache Arrow Flight"
+  ${install_command} --enablerepo=epel arrow-flight-glib-devel-${package_version}
+  ${install_command} --enablerepo=epel arrow-flight-glib-doc-${package_version}
+  echo "::endgroup::"
 fi
 
 if [ "${have_python}" = "yes" ]; then
+  echo "::group::Test libarrow-python"
   ${install_command} --enablerepo=epel arrow-python-devel-${package_version}
+  echo "::endgroup::"
 fi
 
+echo "::group::Test Plasma"
 if [ "${have_glib}" = "yes" ]; then
   ${install_command} --enablerepo=epel plasma-glib-devel-${package_version}
   ${install_command} --enablerepo=epel plasma-glib-doc-${package_version}
 else
   ${install_command} --enablerepo=epel plasma-devel-${package_version}
 fi
-
-if [ "${have_flight}" = "yes" ]; then
-  ${install_command} --enablerepo=epel arrow-flight-glib-devel-${package_version}
-  ${install_command} --enablerepo=epel arrow-flight-glib-doc-${package_version}
-fi
+echo "::endgroup::"
 
 if [ "${have_gandiva}" = "yes" ]; then
+  echo "::group::Test Gandiva"
   if [ "${have_glib}" = "yes" ]; then
     ${install_command} --enablerepo=epel gandiva-glib-devel-${package_version}
     ${install_command} --enablerepo=epel gandiva-glib-doc-${package_version}
   else
     ${install_command} --enablerepo=epel gandiva-devel-${package_version}
   fi
+  echo "::endgroup::"
 fi
 
 if [ "${have_parquet}" = "yes" ]; then
+  echo "::group::Test Apache Parquet"
   if [ "${have_glib}" = "yes" ]; then
     ${install_command} --enablerepo=epel parquet-glib-devel-${package_version}
     ${install_command} --enablerepo=epel parquet-glib-doc-${package_version}
   else
     ${install_command} --enablerepo=epel parquet-devel-${package_version}
   fi
+  echo "::endgroup::"
 fi
diff --git a/dev/tasks/homebrew-formulae/apache-arrow-glib.rb b/dev/tasks/homebrew-formulae/apache-arrow-glib.rb
index 39e7a69979..7ad3ee12df 100644
--- a/dev/tasks/homebrew-formulae/apache-arrow-glib.rb
+++ b/dev/tasks/homebrew-formulae/apache-arrow-glib.rb
@@ -42,6 +42,7 @@ class ApacheArrowGlib < Formula
   depends_on "meson" => :build
   depends_on "ninja" => :build
   depends_on "pkg-config" => :build
+  depends_on "vala" => :build
   depends_on "apache-arrow"
   depends_on "glib"
 
@@ -53,7 +54,7 @@ class ApacheArrowGlib < Formula
 
   def install
     mkdir "build" do
-      system "meson", *std_meson_args, "../c_glib"
+      system "meson", *std_meson_args, "-Dvala=true", "../c_glib"
       system "ninja", "-v"
       system "ninja", "install", "-v"
     end
diff --git a/dev/tasks/linux-packages/Rakefile b/dev/tasks/linux-packages/Rakefile
index a1d4db6314..421d26c913 100644
--- a/dev/tasks/linux-packages/Rakefile
+++ b/dev/tasks/linux-packages/Rakefile
@@ -138,8 +138,9 @@ class LocalBinaryTask < BinaryTask
     verify_command_line = [
       "docker",
       "run",
-      "--rm",
       "--log-driver", "none",
+      "--rm",
+      "--security-opt", "seccomp=unconfined",
       "--volume", "#{File.expand_path(arrow_source_dir)}:/arrow:delegated",
     ]
     if $stdin.tty?
diff --git a/dev/tasks/linux-packages/apache-arrow/apt/debian-bookworm/Dockerfile b/dev/tasks/linux-packages/apache-arrow/apt/debian-bookworm/Dockerfile
index 24ece519fc..152ac08a7c 100644
--- a/dev/tasks/linux-packages/apache-arrow/apt/debian-bookworm/Dockerfile
+++ b/dev/tasks/linux-packages/apache-arrow/apt/debian-bookworm/Dockerfile
@@ -73,6 +73,7 @@ RUN \
     python3-pip \
     rapidjson-dev \
     tzdata \
+    valac \
     zlib1g-dev && \
   if apt list | grep '^nvidia-cuda-toolkit/'; then \
     apt install -y -V ${quiet} nvidia-cuda-toolkit; \
diff --git a/dev/tasks/linux-packages/apache-arrow/apt/debian-bullseye/Dockerfile b/dev/tasks/linux-packages/apache-arrow/apt/debian-bullseye/Dockerfile
index 23e97bfaad..440a07f09c 100644
--- a/dev/tasks/linux-packages/apache-arrow/apt/debian-bullseye/Dockerfile
+++ b/dev/tasks/linux-packages/apache-arrow/apt/debian-bullseye/Dockerfile
@@ -73,6 +73,7 @@ RUN \
     python3-pip \
     rapidjson-dev \
     tzdata \
+    valac \
     zlib1g-dev && \
   if apt list | grep '^nvidia-cuda-toolkit/'; then \
     apt install -y -V ${quiet} nvidia-cuda-toolkit; \
diff --git a/dev/tasks/linux-packages/apache-arrow/apt/debian-buster/Dockerfile b/dev/tasks/linux-packages/apache-arrow/apt/debian-buster/Dockerfile
index c95c232450..83d0089500 100644
--- a/dev/tasks/linux-packages/apache-arrow/apt/debian-buster/Dockerfile
+++ b/dev/tasks/linux-packages/apache-arrow/apt/debian-buster/Dockerfile
@@ -70,6 +70,7 @@ RUN \
     python3-pip \
     rapidjson-dev \
     tzdata \
+    valac \
     zlib1g-dev && \
   apt install -y -V -t buster-backports ${quiet} \
     clang-11 \
diff --git a/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-bionic/Dockerfile b/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-bionic/Dockerfile
index e132d6e4eb..b897fa73a3 100644
--- a/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-bionic/Dockerfile
+++ b/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-bionic/Dockerfile
@@ -63,6 +63,7 @@ RUN \
     python3-wheel \
     rapidjson-dev \
     tzdata \
+    valac \
     zlib1g-dev && \
   (echo "includedir=/usr/include" && \
    echo "libdir=/usr/lib/$(dpkg-architecture -qDEB_HOST_MULTIARCH)" && \
diff --git a/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-focal/Dockerfile b/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-focal/Dockerfile
index b449678ba0..5abee7c2e0 100644
--- a/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-focal/Dockerfile
+++ b/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-focal/Dockerfile
@@ -68,6 +68,7 @@ RUN \
     python3-setuptools \
     rapidjson-dev \
     tzdata \
+    valac \
     zlib1g-dev && \
   if apt list | grep '^nvidia-cuda-toolkit/'; then \
     apt install -y -V ${quiet} nvidia-cuda-toolkit; \
diff --git a/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-impish/Dockerfile b/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-impish/Dockerfile
index bb7554e55b..0959ba5a2a 100644
--- a/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-impish/Dockerfile
+++ b/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-impish/Dockerfile
@@ -72,6 +72,7 @@ RUN \
     python3-setuptools \
     rapidjson-dev \
     tzdata \
+    valac \
     zlib1g-dev && \
   if apt list | grep -q '^libcuda1'; then \
     apt install -y -V ${quiet} nvidia-cuda-toolkit; \
diff --git a/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-jammy/Dockerfile b/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-jammy/Dockerfile
index b10920efbf..7e95c37642 100644
--- a/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-jammy/Dockerfile
+++ b/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-jammy/Dockerfile
@@ -72,6 +72,7 @@ RUN \
     python3-setuptools \
     rapidjson-dev \
     tzdata \
+    valac \
     zlib1g-dev && \
   if apt list | grep -q '^libcuda1'; then \
     apt install -y -V ${quiet} nvidia-cuda-toolkit; \
diff --git a/dev/tasks/linux-packages/apache-arrow/debian/control.in b/dev/tasks/linux-packages/apache-arrow/debian/control.in
index 79af9bbaee..27c3e0e31c 100644
--- a/dev/tasks/linux-packages/apache-arrow/debian/control.in
+++ b/dev/tasks/linux-packages/apache-arrow/debian/control.in
@@ -34,6 +34,7 @@ Build-Depends:
 @USE_SYSTEM_GRPC@  protobuf-compiler-grpc,
 @ENABLE_PYTHON@  python3-dev,
 @ENABLE_PYTHON@  python3-numpy,
+  valac,
   tzdata,
   zlib1g-dev
 Build-Depends-Indep: libglib2.0-doc
diff --git a/dev/tasks/linux-packages/apache-arrow/debian/libarrow-cuda-glib-dev.install b/dev/tasks/linux-packages/apache-arrow/debian/libarrow-cuda-glib-dev.install
index 778ae5fd74..8c707f5314 100644
--- a/dev/tasks/linux-packages/apache-arrow/debian/libarrow-cuda-glib-dev.install
+++ b/dev/tasks/linux-packages/apache-arrow/debian/libarrow-cuda-glib-dev.install
@@ -2,3 +2,4 @@ usr/include/arrow-cuda-glib/
 usr/lib/*/libarrow-cuda-glib.so
 usr/lib/*/pkgconfig/arrow-cuda-glib.pc
 usr/share/gir-1.0/ArrowCUDA-1.0.gir
+usr/share/vala/vapi/arrow-cuda-glib.*
diff --git a/dev/tasks/linux-packages/apache-arrow/debian/libarrow-dataset-glib-dev.install b/dev/tasks/linux-packages/apache-arrow/debian/libarrow-dataset-glib-dev.install
index 4c50bde975..d02aeb4c24 100644
--- a/dev/tasks/linux-packages/apache-arrow/debian/libarrow-dataset-glib-dev.install
+++ b/dev/tasks/linux-packages/apache-arrow/debian/libarrow-dataset-glib-dev.install
@@ -2,3 +2,4 @@ usr/include/arrow-dataset-glib/
 usr/lib/*/libarrow-dataset-glib.so
 usr/lib/*/pkgconfig/arrow-dataset-glib.pc
 usr/share/gir-1.0/ArrowDataset-1.0.gir
+usr/share/vala/vapi/arrow-dataset-glib.*
diff --git a/dev/tasks/linux-packages/apache-arrow/debian/libarrow-flight-glib-dev.install b/dev/tasks/linux-packages/apache-arrow/debian/libarrow-flight-glib-dev.install
index 8a8dee3ac5..6475e6516a 100644
--- a/dev/tasks/linux-packages/apache-arrow/debian/libarrow-flight-glib-dev.install
+++ b/dev/tasks/linux-packages/apache-arrow/debian/libarrow-flight-glib-dev.install
@@ -2,3 +2,4 @@ usr/include/arrow-flight-glib/
 usr/lib/*/libarrow-flight-glib.so
 usr/lib/*/pkgconfig/arrow-flight-glib.pc
 usr/share/gir-1.0/ArrowFlight-1.0.gir
+usr/share/vala/vapi/arrow-flight-glib.*
diff --git a/dev/tasks/linux-packages/apache-arrow/debian/libarrow-glib-dev.install b/dev/tasks/linux-packages/apache-arrow/debian/libarrow-glib-dev.install
index f6de7eedb6..b029108f9b 100644
--- a/dev/tasks/linux-packages/apache-arrow/debian/libarrow-glib-dev.install
+++ b/dev/tasks/linux-packages/apache-arrow/debian/libarrow-glib-dev.install
@@ -4,3 +4,4 @@ usr/lib/*/pkgconfig/arrow-glib.pc
 usr/lib/*/pkgconfig/arrow-orc-glib.pc
 usr/share/arrow-glib/example/
 usr/share/gir-1.0/Arrow-1.0.gir
+usr/share/vala/vapi/arrow-glib.*
diff --git a/dev/tasks/linux-packages/apache-arrow/debian/libgandiva-glib-dev.install b/dev/tasks/linux-packages/apache-arrow/debian/libgandiva-glib-dev.install
index fe7d8bb793..4243be9009 100644
--- a/dev/tasks/linux-packages/apache-arrow/debian/libgandiva-glib-dev.install
+++ b/dev/tasks/linux-packages/apache-arrow/debian/libgandiva-glib-dev.install
@@ -2,3 +2,4 @@ usr/include/gandiva-glib/
 usr/lib/*/libgandiva-glib.so
 usr/lib/*/pkgconfig/gandiva-glib.pc
 usr/share/gir-1.0/Gandiva-1.0.gir
+usr/share/vala/vapi/gandiva-glib.*
diff --git a/dev/tasks/linux-packages/apache-arrow/debian/libparquet-glib-dev.install b/dev/tasks/linux-packages/apache-arrow/debian/libparquet-glib-dev.install
index 9cce737a71..275da41d21 100644
--- a/dev/tasks/linux-packages/apache-arrow/debian/libparquet-glib-dev.install
+++ b/dev/tasks/linux-packages/apache-arrow/debian/libparquet-glib-dev.install
@@ -2,3 +2,4 @@ usr/include/parquet-glib/
 usr/lib/*/libparquet-glib.so
 usr/lib/*/pkgconfig/parquet-glib.pc
 usr/share/gir-1.0/Parquet-1.0.gir
+usr/share/vala/vapi/parquet-glib.*
diff --git a/dev/tasks/linux-packages/apache-arrow/debian/libplasma-glib-dev.install b/dev/tasks/linux-packages/apache-arrow/debian/libplasma-glib-dev.install
index 7800681d20..7150fc4e58 100644
--- a/dev/tasks/linux-packages/apache-arrow/debian/libplasma-glib-dev.install
+++ b/dev/tasks/linux-packages/apache-arrow/debian/libplasma-glib-dev.install
@@ -2,3 +2,4 @@ usr/include/plasma-glib/
 usr/lib/*/libplasma-glib.so
 usr/lib/*/pkgconfig/plasma-glib.pc
 usr/share/gir-1.0/Plasma-1.0.gir
+usr/share/vala/vapi/plasma-glib.*
diff --git a/dev/tasks/linux-packages/apache-arrow/debian/rules b/dev/tasks/linux-packages/apache-arrow/debian/rules
index 8b4b67f15a..e6845ac5df 100755
--- a/dev/tasks/linux-packages/apache-arrow/debian/rules
+++ b/dev/tasks/linux-packages/apache-arrow/debian/rules
@@ -74,7 +74,8 @@ override_dh_auto_build:
 	  --						\
 	  -Darrow_cpp_build_type=$(BUILD_TYPE)		\
 	  -Darrow_cpp_build_dir=../cpp_build		\
-	  -Dgtk_doc=true
+	  -Dgtk_doc=true				\
+	  -Dvala=true
 	env							\
 	  LD_LIBRARY_PATH=$(CURDIR)/cpp_build/$(BUILD_TYPE)	\
 	    dh_auto_build					\
diff --git a/dev/tasks/linux-packages/apache-arrow/yum/almalinux-8/Dockerfile b/dev/tasks/linux-packages/apache-arrow/yum/almalinux-8/Dockerfile
index 01c9662488..df338a2c25 100644
--- a/dev/tasks/linux-packages/apache-arrow/yum/almalinux-8/Dockerfile
+++ b/dev/tasks/linux-packages/apache-arrow/yum/almalinux-8/Dockerfile
@@ -61,5 +61,6 @@ RUN \
     snappy-devel \
     tar \
     # utf8proc-devel \
+    vala-devel \
     zlib-devel && \
   dnf clean ${quiet} all
diff --git a/dev/tasks/linux-packages/apache-arrow/yum/amazon-linux-2/Dockerfile b/dev/tasks/linux-packages/apache-arrow/yum/amazon-linux-2/Dockerfile
index 2468e60e8a..4b885a2c41 100644
--- a/dev/tasks/linux-packages/apache-arrow/yum/amazon-linux-2/Dockerfile
+++ b/dev/tasks/linux-packages/apache-arrow/yum/amazon-linux-2/Dockerfile
@@ -49,6 +49,7 @@ RUN \
     snappy-devel \
     tar \
     utf8proc-devel \
+    vala-devel \
     zlib-devel && \
   # Install ninja-build dependencies in amzn2-core
   yum install -y ${quiet} ninja-build && \
diff --git a/dev/tasks/linux-packages/apache-arrow/yum/arrow.spec.in b/dev/tasks/linux-packages/apache-arrow/yum/arrow.spec.in
index 7884af7bb9..ad6cd6de69 100644
--- a/dev/tasks/linux-packages/apache-arrow/yum/arrow.spec.in
+++ b/dev/tasks/linux-packages/apache-arrow/yum/arrow.spec.in
@@ -115,6 +115,7 @@ BuildRequires:	ncurses-devel
 
 BuildRequires:	gobject-introspection-devel
 BuildRequires:	gtk-doc
+BuildRequires:	vala-devel
 
 %description
 Apache Arrow is a data processing library for analysis.
@@ -179,7 +180,8 @@ meson setup build \
   --prefix=%{_prefix} \
   -Darrow_cpp_build_dir=../cpp/build \
   -Darrow_cpp_build_type=$cpp_build_type \
-  -Dgtk_doc=true
+  -Dgtk_doc=true \
+  -Dvala=true
 LD_LIBRARY_PATH=$PWD/../cpp/build/$cpp_build_type \
   ninja -C build %{?_smp_mflags}
 cd -
@@ -600,6 +602,7 @@ Libraries and header files for Apache Arrow GLib.
 %{_libdir}/pkgconfig/arrow-orc-glib.pc
 %{_libdir}/girepository-1.0/Arrow-1.0.typelib
 %{_datadir}/arrow-glib/example/
+%{_datadir}/vala/vapi/arrow-glib.*
 
 %package glib-doc
 Summary:	Documentation for Apache Arrow GLib
@@ -647,6 +650,7 @@ Libraries and header files for Apache Arrow Dataset GLib.
 %{_libdir}/libarrow-dataset-glib.so
 %{_libdir}/pkgconfig/arrow-dataset-glib.pc
 %{_libdir}/girepository-1.0/ArrowDataset-1.0.typelib
+%{_datadir}/vala/vapi/arrow-dataset-glib.*
 
 %package dataset-glib-doc
 Summary:	Documentation for Apache Arrow Dataset GLib
@@ -694,6 +698,7 @@ Libraries and header files for Apache Arrow Flight GLib.
 %{_libdir}/libarrow-flight-glib.so
 %{_libdir}/pkgconfig/arrow-flight-glib.pc
 %{_libdir}/girepository-1.0/ArrowFlight-1.0.typelib
+%{_datadir}/vala/vapi/arrow-flight-glib.*
 
 %package flight-glib-doc
 Summary:	Documentation for Apache Arrow Flight GLib
@@ -742,6 +747,7 @@ Libraries and header files for Gandiva GLib.
 %{_libdir}/libgandiva-glib.so
 %{_libdir}/pkgconfig/gandiva-glib.pc
 %{_libdir}/girepository-1.0/Gandiva-1.0.typelib
+%{_datadir}/vala/vapi/gandiva-glib.*
 
 %package -n gandiva-glib-doc
 Summary:	Documentation for Gandiva GLib
@@ -789,6 +795,7 @@ Libraries and header files for Plasma GLib.
 %{_libdir}/libplasma-glib.so
 %{_libdir}/pkgconfig/plasma-glib.pc
 %{_libdir}/girepository-1.0/Plasma-1.0.typelib
+%{_datadir}/vala/vapi/plasma-glib.*
 
 %package -n plasma-glib-doc
 Summary:	Documentation for Plasma GLib
@@ -835,6 +842,7 @@ Libraries and header files for Apache Parquet GLib.
 %{_libdir}/libparquet-glib.so
 %{_libdir}/pkgconfig/parquet-glib.pc
 %{_libdir}/girepository-1.0/Parquet-1.0.typelib
+%{_datadir}/vala/vapi/parquet-glib.*
 
 %package -n parquet-glib-doc
 Summary:	Documentation for Apache Parquet GLib
diff --git a/dev/tasks/linux-packages/apache-arrow/yum/centos-7/Dockerfile b/dev/tasks/linux-packages/apache-arrow/yum/centos-7/Dockerfile
index 46cb79924f..2cbef78621 100644
--- a/dev/tasks/linux-packages/apache-arrow/yum/centos-7/Dockerfile
+++ b/dev/tasks/linux-packages/apache-arrow/yum/centos-7/Dockerfile
@@ -53,6 +53,7 @@ RUN \
     rpmdevtools \
     snappy-devel \
     tar \
+    vala-devel \
     zlib-devel && \
   yum clean ${quiet} all
 
diff --git a/dev/tasks/linux-packages/apache-arrow/yum/centos-8-stream/Dockerfile b/dev/tasks/linux-packages/apache-arrow/yum/centos-8-stream/Dockerfile
index c9e8109f78..14608bc5e6 100644
--- a/dev/tasks/linux-packages/apache-arrow/yum/centos-8-stream/Dockerfile
+++ b/dev/tasks/linux-packages/apache-arrow/yum/centos-8-stream/Dockerfile
@@ -61,5 +61,6 @@ RUN \
     snappy-devel \
     tar \
     utf8proc-devel \
+    vala-devel \
     zlib-devel && \
   dnf clean ${quiet} all