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 223a067  ARROW-11858: [GLib][Gandiva] Add Gandiva::Filter and related 
functions
223a067 is described below

commit 223a067bafd08354ebb5378913051c642c0a4b4d
Author: Sutou Kouhei <[email protected]>
AuthorDate: Thu Apr 1 14:14:31 2021 +0900

    ARROW-11858: [GLib][Gandiva] Add Gandiva::Filter and related functions
    
    Closes #9856 from kou/glib-gandiva-filter
    
    Authored-by: Sutou Kouhei <[email protected]>
    Signed-off-by: Sutou Kouhei <[email protected]>
---
 c_glib/doc/gandiva-glib/gandiva-glib-docs.xml      |  12 +
 c_glib/gandiva-glib/expression.cpp                 |  58 ++++
 c_glib/gandiva-glib/expression.h                   |  23 +-
 c_glib/gandiva-glib/expression.hpp                 |  14 +-
 c_glib/gandiva-glib/filter.cpp                     | 261 ++++++++++++++++
 c_glib/gandiva-glib/{projector.h => filter.h}      |  28 +-
 c_glib/gandiva-glib/{projector.hpp => filter.hpp}  |  12 +-
 c_glib/gandiva-glib/gandiva-glib.h                 |   2 +
 c_glib/gandiva-glib/gandiva-glib.hpp               |   2 +
 c_glib/gandiva-glib/meson.build                    |  12 +-
 c_glib/gandiva-glib/node.cpp                       |   6 +-
 c_glib/gandiva-glib/projector.cpp                  | 209 ++++++++++++-
 c_glib/gandiva-glib/projector.h                    |  44 ++-
 c_glib/gandiva-glib/projector.hpp                  |  14 +-
 c_glib/gandiva-glib/selection-vector.cpp           | 327 +++++++++++++++++++++
 c_glib/gandiva-glib/selection-vector.h             | 128 ++++++++
 .../{projector.hpp => selection-vector.hpp}        |  11 +-
 c_glib/gandiva-glib/version.h.in                   |  23 ++
 c_glib/test/gandiva/test-condition.rb              |  35 +++
 .../gandiva/{test-projector.rb => test-filter.rb}  |  41 ++-
 c_glib/test/gandiva/test-projector.rb              |  41 +--
 c_glib/test/gandiva/test-selectable-projector.rb   |  74 +++++
 c_glib/test/gandiva/test-selection-vector.rb       |  42 +++
 23 files changed, 1329 insertions(+), 90 deletions(-)

diff --git a/c_glib/doc/gandiva-glib/gandiva-glib-docs.xml 
b/c_glib/doc/gandiva-glib/gandiva-glib-docs.xml
index c90f537..182bbfb 100644
--- a/c_glib/doc/gandiva-glib/gandiva-glib-docs.xml
+++ b/c_glib/doc/gandiva-glib/gandiva-glib-docs.xml
@@ -42,6 +42,14 @@
       <title>Expression</title>
       <xi:include href="xml/expression.xml"/>
     </chapter>
+    <chapter id="filter">
+      <title>Filter</title>
+      <xi:include href="xml/filter.xml"/>
+    </chapter>
+    <chapter id="selection-vector">
+      <title>Selection vector</title>
+      <xi:include href="xml/selection-vector.xml"/>
+    </chapter>
     <chapter id="projector">
       <title>Projector</title>
       <xi:include href="xml/projector.xml"/>
@@ -92,6 +100,10 @@
     <title>Index of deprecated API</title>
     <xi:include href="xml/api-index-deprecated.xml"><xi:fallback 
/></xi:include>
   </index>
+  <index id="api-index-4-0-0" role="4.0.0">
+    <title>Index of new symbols in 4.0.0</title>
+    <xi:include href="xml/api-index-4.0.0.xml"><xi:fallback /></xi:include>
+  </index>
   <index id="api-index-1-0-0" role="1.0.0">
     <title>Index of new symbols in 1.0.0</title>
     <xi:include href="xml/api-index-1.0.0.xml"><xi:fallback /></xi:include>
diff --git a/c_glib/gandiva-glib/expression.cpp 
b/c_glib/gandiva-glib/expression.cpp
index d3c2f58..2ad98bf 100644
--- a/c_glib/gandiva-glib/expression.cpp
+++ b/c_glib/gandiva-glib/expression.cpp
@@ -36,6 +36,8 @@ G_BEGIN_DECLS
  * #GGandivaExpression is a class for an expression tree with a root node,
  * and a result field.
  *
+ * #GGandivaCondition is a class for an expression that returns boolean.
+ *
  * Since: 0.12.0
  */
 
@@ -217,6 +219,40 @@ ggandiva_expression_to_string(GGandivaExpression 
*expression)
   return g_strndup(string.data(), string.size());
 }
 
+
+G_DEFINE_TYPE(GGandivaCondition,
+              ggandiva_condition,
+              GGANDIVA_TYPE_EXPRESSION)
+
+static void
+ggandiva_condition_init(GGandivaCondition *object)
+{
+}
+
+static void
+ggandiva_condition_class_init(GGandivaConditionClass *klass)
+{
+}
+
+/**
+ * ggandiva_condition_new:
+ * @root_node: The root node for the condition.
+ *
+ * Returns: A newly created #GGandivaCondition.
+ *
+ * Since: 4.0.0
+ */
+GGandivaCondition *
+ggandiva_condition_new(GGandivaNode *root_node)
+{
+  auto gandiva_root_node = ggandiva_node_get_raw(root_node);
+  auto gandiva_condition =
+    gandiva::TreeExprBuilder::MakeCondition(gandiva_root_node);
+  return ggandiva_condition_new_raw(&gandiva_condition,
+                                    root_node);
+}
+
+
 G_END_DECLS
 
 GGandivaExpression *
@@ -238,3 +274,25 @@ ggandiva_expression_get_raw(GGandivaExpression *expression)
   auto priv = GGANDIVA_EXPRESSION_GET_PRIVATE(expression);
   return priv->expression;
 }
+
+
+GGandivaCondition *
+ggandiva_condition_new_raw(std::shared_ptr<gandiva::Condition> 
*gandiva_condition,
+                           GGandivaNode *root_node)
+{
+  auto arrow_result_field = (*gandiva_condition)->result();
+  auto result_field = garrow_field_new_raw(&arrow_result_field, nullptr);
+  auto condition = g_object_new(GGANDIVA_TYPE_CONDITION,
+                                "expression", gandiva_condition,
+                                "root-node", root_node,
+                                "result-field", result_field,
+                                NULL);
+  return GGANDIVA_CONDITION(condition);
+}
+
+std::shared_ptr<gandiva::Condition>
+ggandiva_condition_get_raw(GGandivaCondition *condition)
+{
+  return std::static_pointer_cast<gandiva::Condition>(
+    ggandiva_expression_get_raw(GGANDIVA_EXPRESSION(condition)));
+}
diff --git a/c_glib/gandiva-glib/expression.h b/c_glib/gandiva-glib/expression.h
index f86b6c5..0a720d9 100644
--- a/c_glib/gandiva-glib/expression.h
+++ b/c_glib/gandiva-glib/expression.h
@@ -37,8 +37,27 @@ struct _GGandivaExpressionClass
   GObjectClass parent_class;
 };
 
-GGandivaExpression *ggandiva_expression_new(GGandivaNode *root_node,
-                                            GArrowField *result_field);
+GGandivaExpression *
+ggandiva_expression_new(GGandivaNode *root_node,
+                        GArrowField *result_field);
 gchar *ggandiva_expression_to_string(GGandivaExpression *expression);
 
+
+#define GGANDIVA_TYPE_CONDITION (ggandiva_condition_get_type())
+G_DECLARE_DERIVABLE_TYPE(GGandivaCondition,
+                         ggandiva_condition,
+                         GGANDIVA,
+                         CONDITION,
+                         GGandivaExpression)
+
+struct _GGandivaConditionClass
+{
+  GGandivaExpressionClass parent_class;
+};
+
+GGANDIVA_AVAILABLE_IN_4_0
+GGandivaCondition *
+ggandiva_condition_new(GGandivaNode *root_node);
+
+
 G_END_DECLS
diff --git a/c_glib/gandiva-glib/expression.hpp 
b/c_glib/gandiva-glib/expression.hpp
index a0d0e64..45b6593 100644
--- a/c_glib/gandiva-glib/expression.hpp
+++ b/c_glib/gandiva-glib/expression.hpp
@@ -26,8 +26,14 @@
 
 #include <gandiva-glib/expression.h>
 
-GGandivaExpression
-*ggandiva_expression_new_raw(std::shared_ptr<gandiva::Expression> 
*gandiva_expression,
-                             GGandivaNode *root_node,
-                             GArrowField *result_field);
+GGandivaExpression *
+ggandiva_expression_new_raw(std::shared_ptr<gandiva::Expression> 
*gandiva_expression,
+                            GGandivaNode *root_node,
+                            GArrowField *result_field);
 std::shared_ptr<gandiva::Expression> 
ggandiva_expression_get_raw(GGandivaExpression *expression);
+
+GGandivaCondition
+*ggandiva_condition_new_raw(std::shared_ptr<gandiva::Condition> 
*gandiva_expression,
+                            GGandivaNode *root_node);
+std::shared_ptr<gandiva::Condition>
+ggandiva_condition_get_raw(GGandivaCondition *condition);
diff --git a/c_glib/gandiva-glib/filter.cpp b/c_glib/gandiva-glib/filter.cpp
new file mode 100644
index 0000000..34e04fc
--- /dev/null
+++ b/c_glib/gandiva-glib/filter.cpp
@@ -0,0 +1,261 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <limits>
+
+#include <arrow-glib/basic-array.hpp>
+#include <arrow-glib/error.hpp>
+#include <arrow-glib/record-batch.hpp>
+#include <arrow-glib/schema.hpp>
+
+#include <gandiva-glib/expression.hpp>
+#include <gandiva-glib/filter.hpp>
+#include <gandiva-glib/selection-vector.hpp>
+
+G_BEGIN_DECLS
+
+/**
+ * SECTION: filter
+ * @title: Filter classes
+ * @include: gandiva-glib/gandiva-glib.h
+ *
+ * #GGandivaFilter is a class for selecting records by a specific
+ * condition.
+ *
+ * Since: 4.0.0
+ */
+
+typedef struct GGandivaFilterPrivate_ {
+  std::shared_ptr<gandiva::Filter> filter;
+  GArrowSchema *schema;
+  GGandivaCondition *condition;
+} GGandivaFilterPrivate;
+
+enum {
+  PROP_FILTER = 1,
+  PROP_SCHEMA,
+  PROP_CONDITION,
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE(GGandivaFilter,
+                           ggandiva_filter,
+                           G_TYPE_OBJECT)
+
+#define GGANDIVA_FILTER_GET_PRIVATE(obj)         \
+  static_cast<GGandivaFilterPrivate *>(          \
+     ggandiva_filter_get_instance_private(       \
+       GGANDIVA_FILTER(obj)))
+
+static void
+ggandiva_filter_dispose(GObject *object)
+{
+  auto priv = GGANDIVA_FILTER_GET_PRIVATE(object);
+
+  if (priv->schema) {
+    g_object_unref(priv->schema);
+    priv->schema = nullptr;
+  }
+
+  if (priv->condition) {
+    g_object_unref(priv->condition);
+    priv->condition = nullptr;
+  }
+
+  G_OBJECT_CLASS(ggandiva_filter_parent_class)->dispose(object);
+}
+
+static void
+ggandiva_filter_finalize(GObject *object)
+{
+  auto priv = GGANDIVA_FILTER_GET_PRIVATE(object);
+
+  priv->filter.~shared_ptr();
+
+  G_OBJECT_CLASS(ggandiva_filter_parent_class)->finalize(object);
+}
+
+static void
+ggandiva_filter_set_property(GObject *object,
+                             guint prop_id,
+                             const GValue *value,
+                             GParamSpec *pspec)
+{
+  auto priv = GGANDIVA_FILTER_GET_PRIVATE(object);
+
+  switch (prop_id) {
+  case PROP_FILTER:
+    priv->filter =
+      *static_cast<std::shared_ptr<gandiva::Filter> 
*>(g_value_get_pointer(value));
+    break;
+  case PROP_SCHEMA:
+    priv->schema = GARROW_SCHEMA(g_value_dup_object(value));
+    break;
+  case PROP_CONDITION:
+    priv->condition = GGANDIVA_CONDITION(g_value_dup_object(value));
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
+}
+
+static void
+ggandiva_filter_get_property(GObject *object,
+                             guint prop_id,
+                             GValue *value,
+                             GParamSpec *pspec)
+{
+  auto priv = GGANDIVA_FILTER_GET_PRIVATE(object);
+
+  switch (prop_id) {
+  case PROP_SCHEMA:
+    g_value_set_object(value, priv->schema);
+    break;
+  case PROP_CONDITION:
+    g_value_set_object(value, priv->condition);
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
+}
+
+static void
+ggandiva_filter_init(GGandivaFilter *object)
+{
+  auto priv = GGANDIVA_FILTER_GET_PRIVATE(object);
+  new(&priv->filter) std::shared_ptr<gandiva::Filter>;
+}
+
+static void
+ggandiva_filter_class_init(GGandivaFilterClass *klass)
+{
+  auto gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->dispose      = ggandiva_filter_dispose;
+  gobject_class->finalize     = ggandiva_filter_finalize;
+  gobject_class->set_property = ggandiva_filter_set_property;
+  gobject_class->get_property = ggandiva_filter_get_property;
+
+  GParamSpec *spec;
+  spec = g_param_spec_pointer("filter",
+                              "Filter",
+                              "The raw std::shared<gandiva::Filter> *",
+                              static_cast<GParamFlags>(G_PARAM_WRITABLE |
+                                                       
G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_FILTER, spec);
+
+  spec = g_param_spec_object("schema",
+                             "Schema",
+                             "The schema for input record batch",
+                             GARROW_TYPE_SCHEMA,
+                             static_cast<GParamFlags>(G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_SCHEMA, spec);
+
+  spec = g_param_spec_object("condition",
+                             "Condition",
+                             "The condition for the filter",
+                             GGANDIVA_TYPE_CONDITION,
+                             static_cast<GParamFlags>(G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_CONDITION, spec);
+}
+
+/**
+ * ggandiva_filter_new:
+ * @schema: A #GArrowSchema.
+ * @condition: The condition to be used.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (nullable): A newly created #GGandivaFilter on success,
+ *   %NULL on error.
+ *
+ * Since: 4.0.0
+ */
+GGandivaFilter *
+ggandiva_filter_new(GArrowSchema *schema,
+                    GGandivaCondition *condition,
+                    GError **error)
+{
+  auto arrow_schema = garrow_schema_get_raw(schema);
+  auto gandiva_condition = ggandiva_condition_get_raw(condition);
+  std::shared_ptr<gandiva::Filter> gandiva_filter;
+  auto status = gandiva::Filter::Make(arrow_schema,
+                                      gandiva_condition,
+                                      &gandiva_filter);
+  if (garrow_error_check(error, status, "[gandiva][filter][new]")) {
+    return ggandiva_filter_new_raw(&gandiva_filter, schema, condition);
+  } else {
+    return NULL;
+  }
+}
+
+/**
+ * ggandiva_filter_evaluate:
+ * @filter: A #GGandivaFilter.
+ * @record_batch: A #GArrowRecordBatch.
+ * @selection_vector: A #GGandivaSelectionVector that is used as
+ *   output.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: %TRUE on success, %FALSE otherwise.
+ *
+ * Since: 4.0.0
+ */
+gboolean
+ggandiva_filter_evaluate(GGandivaFilter *filter,
+                         GArrowRecordBatch *record_batch,
+                         GGandivaSelectionVector *selection_vector,
+                         GError **error)
+{
+  auto gandiva_filter = ggandiva_filter_get_raw(filter);
+  auto arrow_record_batch = garrow_record_batch_get_raw(record_batch);
+  auto gandiva_selection_vector =
+    ggandiva_selection_vector_get_raw(selection_vector);
+  auto status = gandiva_filter->Evaluate(*arrow_record_batch,
+                                         gandiva_selection_vector);
+  return garrow_error_check(error, status, "[gandiva][filter][evaluate]");
+}
+
+G_END_DECLS
+
+GGandivaFilter *
+ggandiva_filter_new_raw(std::shared_ptr<gandiva::Filter> *gandiva_filter,
+                        GArrowSchema *schema,
+                        GGandivaCondition *condition)
+{
+  auto filter = g_object_new(GGANDIVA_TYPE_FILTER,
+                             "filter", gandiva_filter,
+                             "schema", schema,
+                             "condition", condition,
+                             NULL);
+  return GGANDIVA_FILTER(filter);
+}
+
+std::shared_ptr<gandiva::Filter>
+ggandiva_filter_get_raw(GGandivaFilter *filter)
+{
+  auto priv = GGANDIVA_FILTER_GET_PRIVATE(filter);
+  return priv->filter;
+}
diff --git a/c_glib/gandiva-glib/projector.h b/c_glib/gandiva-glib/filter.h
similarity index 59%
copy from c_glib/gandiva-glib/projector.h
copy to c_glib/gandiva-glib/filter.h
index ae6dead..9a0a5dc 100644
--- a/c_glib/gandiva-glib/projector.h
+++ b/c_glib/gandiva-glib/filter.h
@@ -19,27 +19,31 @@
 
 #pragma once
 
-#include <arrow-glib/arrow-glib.h>
+#include <gandiva-glib/expression.h>
+#include <gandiva-glib/selection-vector.h>
 
 G_BEGIN_DECLS
 
-#define GGANDIVA_TYPE_PROJECTOR (ggandiva_projector_get_type())
-G_DECLARE_DERIVABLE_TYPE(GGandivaProjector,
-                         ggandiva_projector,
+#define GGANDIVA_TYPE_FILTER (ggandiva_filter_get_type())
+G_DECLARE_DERIVABLE_TYPE(GGandivaFilter,
+                         ggandiva_filter,
                          GGANDIVA,
-                         PROJECTOR,
+                         FILTER,
                          GObject)
 
-struct _GGandivaProjectorClass
+struct _GGandivaFilterClass
 {
   GObjectClass parent_class;
 };
 
-GGandivaProjector *ggandiva_projector_new(GArrowSchema *schema,
-                                          GList *expressions,
-                                          GError **error);
-GList *ggandiva_projector_evaluate(GGandivaProjector *projector,
-                                   GArrowRecordBatch *record_batch,
-                                   GError **error);
+GGandivaFilter *
+ggandiva_filter_new(GArrowSchema *schema,
+                    GGandivaCondition *condition,
+                    GError **error);
+gboolean
+ggandiva_filter_evaluate(GGandivaFilter *filter,
+                         GArrowRecordBatch *record_batch,
+                         GGandivaSelectionVector *selection_vector,
+                         GError **error);
 
 G_END_DECLS
diff --git a/c_glib/gandiva-glib/projector.hpp b/c_glib/gandiva-glib/filter.hpp
similarity index 71%
copy from c_glib/gandiva-glib/projector.hpp
copy to c_glib/gandiva-glib/filter.hpp
index 1e9359b..a0bee91 100644
--- a/c_glib/gandiva-glib/projector.hpp
+++ b/c_glib/gandiva-glib/filter.hpp
@@ -21,9 +21,13 @@
 
 #include <memory>
 
-#include <gandiva/projector.h>
+#include <gandiva/filter.h>
 
-#include <gandiva-glib/projector.h>
+#include <gandiva-glib/filter.h>
 
-GGandivaProjector 
*ggandiva_projector_new_raw(std::shared_ptr<gandiva::Projector> 
*gandiva_projector);
-std::shared_ptr<gandiva::Projector> 
ggandiva_projector_get_raw(GGandivaProjector *projector);
+GGandivaFilter *
+ggandiva_filter_new_raw(std::shared_ptr<gandiva::Filter> *gandiva_filter,
+                        GArrowSchema *schema,
+                        GGandivaCondition *condition);
+std::shared_ptr<gandiva::Filter>
+ggandiva_filter_get_raw(GGandivaFilter *filter);
diff --git a/c_glib/gandiva-glib/gandiva-glib.h 
b/c_glib/gandiva-glib/gandiva-glib.h
index 7d1c3d9..9c1a160 100644
--- a/c_glib/gandiva-glib/gandiva-glib.h
+++ b/c_glib/gandiva-glib/gandiva-glib.h
@@ -22,8 +22,10 @@
 #include <gandiva-glib/version.h>
 
 #include <gandiva-glib/expression.h>
+#include <gandiva-glib/filter.h>
 #include <gandiva-glib/function-registry.h>
 #include <gandiva-glib/function-signature.h>
 #include <gandiva-glib/native-function.h>
 #include <gandiva-glib/node.h>
 #include <gandiva-glib/projector.h>
+#include <gandiva-glib/selection-vector.h>
diff --git a/c_glib/gandiva-glib/gandiva-glib.hpp 
b/c_glib/gandiva-glib/gandiva-glib.hpp
index 8d857a3..eb39f58 100644
--- a/c_glib/gandiva-glib/gandiva-glib.hpp
+++ b/c_glib/gandiva-glib/gandiva-glib.hpp
@@ -22,5 +22,7 @@
 #include <gandiva-glib/gandiva-glib.h>
 
 #include <gandiva-glib/expression.hpp>
+#include <gandiva-glib/filter.hpp>
 #include <gandiva-glib/node.hpp>
 #include <gandiva-glib/projector.hpp>
+#include <gandiva-glib/selection-vector.hpp>
diff --git a/c_glib/gandiva-glib/meson.build b/c_glib/gandiva-glib/meson.build
index d4ee81d..5127d67 100644
--- a/c_glib/gandiva-glib/meson.build
+++ b/c_glib/gandiva-glib/meson.build
@@ -21,30 +21,36 @@ project_name = 'gandiva-glib'
 
 sources = files(
   'expression.cpp',
+  'filter.cpp',
   'function-registry.cpp',
   'function-signature.cpp',
-  'node.cpp',
   'native-function.cpp',
+  'node.cpp',
   'projector.cpp',
+  'selection-vector.cpp',
 )
 
 c_headers = files(
   'expression.h',
+  'filter.h',
   'function-registry.h',
   'function-signature.h',
   'gandiva-glib.h',
-  'node.h',
   'native-function.h',
+  'node.h',
   'projector.h',
+  'selection-vector.h',
 )
 
 cpp_headers = files(
   'expression.hpp',
+  'filter.hpp',
   'function-signature.hpp',
   'gandiva-glib.hpp',
-  'node.hpp',
   'native-function.hpp',
+  'node.hpp',
   'projector.hpp',
+  'selection-vector.hpp',
 )
 
 version_h_conf = configuration_data()
diff --git a/c_glib/gandiva-glib/node.cpp b/c_glib/gandiva-glib/node.cpp
index 2810662..68f65c6 100644
--- a/c_glib/gandiva-glib/node.cpp
+++ b/c_glib/gandiva-glib/node.cpp
@@ -116,9 +116,9 @@ enum {
   PROP_RETURN_TYPE
 };
 
-G_DEFINE_TYPE_WITH_PRIVATE(GGandivaNode,
-                           ggandiva_node,
-                           G_TYPE_OBJECT)
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(GGandivaNode,
+                                    ggandiva_node,
+                                    G_TYPE_OBJECT)
 
 #define GGANDIVA_NODE_GET_PRIVATE(object)                       \
   static_cast<GGandivaNodePrivate *>(                           \
diff --git a/c_glib/gandiva-glib/projector.cpp 
b/c_glib/gandiva-glib/projector.cpp
index ebcc487..c1cb19e 100644
--- a/c_glib/gandiva-glib/projector.cpp
+++ b/c_glib/gandiva-glib/projector.cpp
@@ -22,12 +22,13 @@
 #endif
 
 #include <arrow-glib/basic-array.hpp>
+#include <arrow-glib/error.hpp>
 #include <arrow-glib/record-batch.hpp>
 #include <arrow-glib/schema.hpp>
 
-#include <arrow-glib/error.hpp>
 #include <gandiva-glib/expression.hpp>
 #include <gandiva-glib/projector.hpp>
+#include <gandiva-glib/selection-vector.hpp>
 
 G_BEGIN_DECLS
 
@@ -36,19 +37,25 @@ G_BEGIN_DECLS
  * @title: Projector classes
  * @include: gandiva-glib/gandiva-glib.h
  *
- * #GGandivaProjector is a class for building a specific schema
- * and vector of expressions.
+ * #GGandivaProjector is a class that evaluates given expressions
+ * against the given record batches.
+ *
+ * #GGandivaSelectableProjector is a class that evaluates given expressions
+ * against the given selected records in the given record batches.
  *
  * Since: 0.12.0
  */
 
 typedef struct GGandivaProjectorPrivate_ {
   std::shared_ptr<gandiva::Projector> projector;
+  GArrowSchema *schema;
+  GList *expressions;
 } GGandivaProjectorPrivate;
 
 enum {
-  PROP_0,
-  PROP_PROJECTOR
+  PROP_PROJECTOR = 1,
+  PROP_SCHEMA,
+  PROP_EXPRESSIONS,
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE(GGandivaProjector,
@@ -61,6 +68,22 @@ G_DEFINE_TYPE_WITH_PRIVATE(GGandivaProjector,
        GGANDIVA_PROJECTOR(obj)))
 
 static void
+ggandiva_projector_dispose(GObject *object)
+{
+  auto priv = GGANDIVA_PROJECTOR_GET_PRIVATE(object);
+
+  if (priv->schema) {
+    g_object_unref(G_OBJECT(priv->schema));
+    priv->schema = nullptr;
+  }
+
+  g_list_free_full(priv->expressions, g_object_unref);
+  priv->expressions = nullptr;
+
+  G_OBJECT_CLASS(ggandiva_projector_parent_class)->dispose(object);
+}
+
+static void
 ggandiva_projector_finalize(GObject *object)
 {
   auto priv = GGANDIVA_PROJECTOR_GET_PRIVATE(object);
@@ -83,6 +106,33 @@ ggandiva_projector_set_property(GObject *object,
     priv->projector =
       *static_cast<std::shared_ptr<gandiva::Projector> 
*>(g_value_get_pointer(value));
     break;
+  case PROP_SCHEMA:
+    priv->schema = GARROW_SCHEMA(g_value_dup_object(value));
+    break;
+  case PROP_EXPRESSIONS:
+    priv->expressions =
+      g_list_copy_deep(static_cast<GList *>(g_value_get_pointer(value)),
+                       reinterpret_cast<GCopyFunc>(g_object_ref),
+                       nullptr);
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
+}
+
+static void
+ggandiva_projector_get_property(GObject *object,
+                                guint prop_id,
+                                GValue *value,
+                                GParamSpec *pspec)
+{
+  auto priv = GGANDIVA_PROJECTOR_GET_PRIVATE(object);
+
+  switch (prop_id) {
+  case PROP_SCHEMA:
+    g_value_set_object(value, priv->schema);
+    break;
   default:
     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
     break;
@@ -99,19 +149,35 @@ ggandiva_projector_init(GGandivaProjector *object)
 static void
 ggandiva_projector_class_init(GGandivaProjectorClass *klass)
 {
-  GParamSpec *spec;
-
   auto gobject_class = G_OBJECT_CLASS(klass);
 
+  gobject_class->dispose      = ggandiva_projector_dispose;
   gobject_class->finalize     = ggandiva_projector_finalize;
   gobject_class->set_property = ggandiva_projector_set_property;
+  gobject_class->get_property = ggandiva_projector_get_property;
 
+  GParamSpec *spec;
   spec = g_param_spec_pointer("projector",
                               "Projector",
                               "The raw std::shared<gandiva::Projector> *",
                               static_cast<GParamFlags>(G_PARAM_WRITABLE |
                                                        
G_PARAM_CONSTRUCT_ONLY));
   g_object_class_install_property(gobject_class, PROP_PROJECTOR, spec);
+
+  spec = g_param_spec_object("schema",
+                             "Schema",
+                             "The schema of the projector",
+                             GARROW_TYPE_SCHEMA,
+                             static_cast<GParamFlags>(G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_SCHEMA, spec);
+
+  spec = g_param_spec_pointer("expressions",
+                              "Expressions",
+                              "The expressions for the projector",
+                              static_cast<GParamFlags>(G_PARAM_WRITABLE |
+                                                       
G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_EXPRESSIONS, spec);
 }
 
 /**
@@ -143,7 +209,9 @@ ggandiva_projector_new(GArrowSchema *schema,
                             gandiva_expressions,
                             &gandiva_projector);
   if (garrow_error_check(error, status, "[gandiva][projector][new]")) {
-    return ggandiva_projector_new_raw(&gandiva_projector);
+    return ggandiva_projector_new_raw(&gandiva_projector,
+                                      schema,
+                                      expressions);
   } else {
     return NULL;
   }
@@ -185,17 +253,140 @@ ggandiva_projector_evaluate(GGandivaProjector *projector,
   }
 }
 
+
+G_DEFINE_TYPE(GGandivaSelectableProjector,
+              ggandiva_selectable_projector,
+              GGANDIVA_TYPE_PROJECTOR)
+
+static void
+ggandiva_selectable_projector_init(GGandivaSelectableProjector *object)
+{
+}
+
+static void
+ggandiva_selectable_projector_class_init(GGandivaSelectableProjectorClass 
*klass)
+{
+}
+
+/**
+ * ggandiva_selectable_projector_new:
+ * @schema: A #GArrowSchema.
+ * @expressions: (element-type GGandivaExpression): The built expressions.
+ * @mode: A #GGandivaSelectionVectorMode to be used.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (nullable): A newly created #GGandivaProjector on success,
+ *   %NULL on error.
+ *
+ * Since: 4.0.0
+ */
+GGandivaSelectableProjector *
+ggandiva_selectable_projector_new(GArrowSchema *schema,
+                                  GList *expressions,
+                                  GGandivaSelectionVectorMode mode,
+                                  GError **error)
+{
+  auto arrow_schema = garrow_schema_get_raw(schema);
+  std::vector<std::shared_ptr<gandiva::Expression>> gandiva_expressions;
+  for (auto node = expressions; node; node = g_list_next(node)) {
+    auto expression = GGANDIVA_EXPRESSION(node->data);
+    auto gandiva_expression = ggandiva_expression_get_raw(expression);
+    gandiva_expressions.push_back(gandiva_expression);
+  }
+  auto gandiva_mode = static_cast<gandiva::SelectionVector::Mode>(mode);
+  auto gandiva_configuration =
+    gandiva::ConfigurationBuilder::DefaultConfiguration();
+  std::shared_ptr<gandiva::Projector> gandiva_projector;
+  auto status = gandiva_projector->Make(arrow_schema,
+                                        gandiva_expressions,
+                                        gandiva_mode,
+                                        gandiva_configuration,
+                                        &gandiva_projector);
+  if (garrow_error_check(error,
+                         status,
+                         "[gandiva][selectable-projector][new]")) {
+    return ggandiva_selectable_projector_new_raw(&gandiva_projector,
+                                                 schema,
+                                                 expressions);
+  } else {
+    return NULL;
+  }
+}
+
+/**
+ * ggandiva_selectable_projector_evaluate:
+ * @projector: A #GGandivaSelectableProjector.
+ * @record_batch: A #GArrowRecordBatch.
+ * @selection_vector: A #GGandivaSelectionVector that specifies
+ *   the filtered row positions.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (element-type GArrowArray) (nullable) (transfer full):
+ *   The #GArrowArray as the result evaluated on success, %NULL on error.
+ *
+ * Since: 4.0.0
+ */
+GList *
+ggandiva_selectable_projector_evaluate(
+  GGandivaSelectableProjector *projector,
+  GArrowRecordBatch *record_batch,
+  GGandivaSelectionVector *selection_vector,
+  GError **error)
+{
+  auto gandiva_projector =
+    ggandiva_projector_get_raw(GGANDIVA_PROJECTOR(projector));
+  auto arrow_record_batch = garrow_record_batch_get_raw(record_batch);
+  auto gandiva_selection_vector =
+    ggandiva_selection_vector_get_raw(selection_vector).get();
+  auto memory_pool = arrow::default_memory_pool();
+  arrow::ArrayVector arrow_arrays;
+  auto status =
+    gandiva_projector->Evaluate(*arrow_record_batch,
+                                gandiva_selection_vector,
+                                memory_pool,
+                                &arrow_arrays);
+  if (garrow_error_check(error,
+                         status,
+                         "[gandiva][selectable-projector][evaluate]")) {
+    GList *arrays = NULL;
+    for (auto arrow_array : arrow_arrays) {
+      auto array = garrow_array_new_raw(&arrow_array);
+      arrays = g_list_prepend(arrays, array);
+    }
+    return g_list_reverse(arrays);
+  } else {
+    return NULL;
+  }
+}
+
 G_END_DECLS
 
 GGandivaProjector *
-ggandiva_projector_new_raw(std::shared_ptr<gandiva::Projector> 
*gandiva_projector)
+ggandiva_projector_new_raw(
+  std::shared_ptr<gandiva::Projector> *gandiva_projector,
+  GArrowSchema *schema,
+  GList *expressions)
 {
   auto projector = g_object_new(GGANDIVA_TYPE_PROJECTOR,
                                 "projector", gandiva_projector,
+                                "schema", schema,
+                                "expressions", expressions,
                                 NULL);
   return GGANDIVA_PROJECTOR(projector);
 }
 
+GGandivaSelectableProjector *
+ggandiva_selectable_projector_new_raw(
+  std::shared_ptr<gandiva::Projector> *gandiva_projector,
+  GArrowSchema *schema,
+  GList *expressions)
+{
+  auto projector = g_object_new(GGANDIVA_TYPE_SELECTABLE_PROJECTOR,
+                                "projector", gandiva_projector,
+                                NULL);
+  return GGANDIVA_SELECTABLE_PROJECTOR(projector);
+}
+
 std::shared_ptr<gandiva::Projector>
 ggandiva_projector_get_raw(GGandivaProjector *projector)
 {
diff --git a/c_glib/gandiva-glib/projector.h b/c_glib/gandiva-glib/projector.h
index ae6dead..5dd218b 100644
--- a/c_glib/gandiva-glib/projector.h
+++ b/c_glib/gandiva-glib/projector.h
@@ -19,7 +19,7 @@
 
 #pragma once
 
-#include <arrow-glib/arrow-glib.h>
+#include <gandiva-glib/selection-vector.h>
 
 G_BEGIN_DECLS
 
@@ -35,11 +35,41 @@ struct _GGandivaProjectorClass
   GObjectClass parent_class;
 };
 
-GGandivaProjector *ggandiva_projector_new(GArrowSchema *schema,
-                                          GList *expressions,
-                                          GError **error);
-GList *ggandiva_projector_evaluate(GGandivaProjector *projector,
-                                   GArrowRecordBatch *record_batch,
-                                   GError **error);
+GGandivaProjector *
+ggandiva_projector_new(GArrowSchema *schema,
+                       GList *expressions,
+                       GError **error);
+GList *
+ggandiva_projector_evaluate(GGandivaProjector *projector,
+                            GArrowRecordBatch *record_batch,
+                            GError **error);
+
+
+#define GGANDIVA_TYPE_SELECTABLE_PROJECTOR      \
+  (ggandiva_selectable_projector_get_type())
+G_DECLARE_DERIVABLE_TYPE(GGandivaSelectableProjector,
+                         ggandiva_selectable_projector,
+                         GGANDIVA,
+                         SELECTABLE_PROJECTOR,
+                         GGandivaProjector)
+
+struct _GGandivaSelectableProjectorClass
+{
+  GGandivaProjectorClass parent_class;
+};
+
+GGANDIVA_AVAILABLE_IN_4_0
+GGandivaSelectableProjector *
+ggandiva_selectable_projector_new(GArrowSchema *schema,
+                                  GList *expressions,
+                                  GGandivaSelectionVectorMode mode,
+                                  GError **error);
+GGANDIVA_AVAILABLE_IN_4_0
+GList *
+ggandiva_selectable_projector_evaluate(GGandivaSelectableProjector *projector,
+                                       GArrowRecordBatch *record_batch,
+                                       GGandivaSelectionVector 
*selection_vector,
+                                       GError **error);
+
 
 G_END_DECLS
diff --git a/c_glib/gandiva-glib/projector.hpp 
b/c_glib/gandiva-glib/projector.hpp
index 1e9359b..b372f32 100644
--- a/c_glib/gandiva-glib/projector.hpp
+++ b/c_glib/gandiva-glib/projector.hpp
@@ -25,5 +25,15 @@
 
 #include <gandiva-glib/projector.h>
 
-GGandivaProjector 
*ggandiva_projector_new_raw(std::shared_ptr<gandiva::Projector> 
*gandiva_projector);
-std::shared_ptr<gandiva::Projector> 
ggandiva_projector_get_raw(GGandivaProjector *projector);
+GGandivaProjector *
+ggandiva_projector_new_raw(
+  std::shared_ptr<gandiva::Projector> *gandiva_projector,
+  GArrowSchema *schema,
+  GList *expressions);
+GGandivaSelectableProjector *
+ggandiva_selectable_projector_new_raw(
+  std::shared_ptr<gandiva::Projector> *gandiva_projector,
+  GArrowSchema *schema,
+  GList *expressions);
+std::shared_ptr<gandiva::Projector>
+ggandiva_projector_get_raw(GGandivaProjector *projector);
diff --git a/c_glib/gandiva-glib/selection-vector.cpp 
b/c_glib/gandiva-glib/selection-vector.cpp
new file mode 100644
index 0000000..1c1fa04
--- /dev/null
+++ b/c_glib/gandiva-glib/selection-vector.cpp
@@ -0,0 +1,327 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <arrow-glib/basic-array.hpp>
+#include <arrow-glib/error.hpp>
+
+#include <gandiva-glib/selection-vector.hpp>
+
+
+G_BEGIN_DECLS
+
+/**
+ * SECTION: selection-vector
+ * @section_id: selection-vector-classes
+ * @title: Selection vector classes
+ * @include: gandiva-glib/gandiva-glib.h
+ *
+ * #GGandivaSelectionVector is a base class for a selection vector.
+ *
+ * #GGandivaUInt16SelectionVector is a class for a selection vector
+ * that uses 16-bit unsigned integer for each index.
+ *
+ * #GGandivaUInt32SelectionVector is a class for a selection vector
+ * that uses 32-bit unsigned integer for each index.
+ *
+ * #GGandivaUInt64SelectionVector is a class for a selection vector
+ * that uses 64-bit unsigned integer for each index.
+ *
+ * Since: 4.0.0
+ */
+
+typedef struct GGandivaSelectionVectorPrivate_ {
+  std::shared_ptr<gandiva::SelectionVector> selection_vector;
+} GGandivaSelectionVectorPrivate;
+
+enum {
+  PROP_SELECTION_VECTOR = 1,
+};
+
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(GGandivaSelectionVector,
+                                    ggandiva_selection_vector,
+                                    G_TYPE_OBJECT)
+
+#define GGANDIVA_SELECTION_VECTOR_GET_PRIVATE(object)           \
+  static_cast<GGandivaSelectionVectorPrivate *>(                \
+    ggandiva_selection_vector_get_instance_private(             \
+      GGANDIVA_SELECTION_VECTOR(object)))
+
+static void
+ggandiva_selection_vector_finalize(GObject *object)
+{
+  auto priv = GGANDIVA_SELECTION_VECTOR_GET_PRIVATE(object);
+
+  priv->selection_vector.~shared_ptr();
+
+  G_OBJECT_CLASS(ggandiva_selection_vector_parent_class)->finalize(object);
+}
+
+static void
+ggandiva_selection_vector_set_property(GObject *object,
+                                       guint prop_id,
+                                       const GValue *value,
+                                       GParamSpec *pspec)
+{
+  auto priv = GGANDIVA_SELECTION_VECTOR_GET_PRIVATE(object);
+
+  switch (prop_id) {
+  case PROP_SELECTION_VECTOR:
+    priv->selection_vector =
+      *static_cast<std::shared_ptr<gandiva::SelectionVector> *>(
+        g_value_get_pointer(value));
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
+}
+
+static void
+ggandiva_selection_vector_init(GGandivaSelectionVector *object)
+{
+  auto priv = GGANDIVA_SELECTION_VECTOR_GET_PRIVATE(object);
+  new(&priv->selection_vector) std::shared_ptr<gandiva::SelectionVector>;
+}
+
+static void
+ggandiva_selection_vector_class_init(GGandivaSelectionVectorClass *klass)
+{
+  auto gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize     = ggandiva_selection_vector_finalize;
+  gobject_class->set_property = ggandiva_selection_vector_set_property;
+
+  GParamSpec *spec;
+  spec = g_param_spec_pointer("selection-vector",
+                              "Selection vector",
+                              "The raw std::shared<gandiva::SelectionVector> 
*",
+                              static_cast<GParamFlags>(G_PARAM_WRITABLE |
+                                                       
G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_SELECTION_VECTOR, spec);
+}
+
+/**
+ * ggandiva_selection_vector_get_mode:
+ * @selection_vector: A #GGandivaSelectionVector.
+ *
+ * Returns: A #GGandivaSelectionVectorMode for the selection vector.
+ *
+ * Since: 4.0.0
+ */
+GGandivaSelectionVectorMode
+ggandiva_selection_vector_get_mode(GGandivaSelectionVector *selection_vector)
+{
+  auto gandiva_selection_vector =
+    ggandiva_selection_vector_get_raw(selection_vector);
+  auto gandiva_mode = gandiva_selection_vector->GetMode();
+  return static_cast<GGandivaSelectionVectorMode>(gandiva_mode);
+}
+
+/**
+ * ggandiva_selection_vector_to_array:
+ * @selection_vector: A #GGandivaSelectionVector.
+ *
+ * Returns: (transfer full): A #GArrowArray that has the same content
+ *   of the selection vector.
+ *
+ * Since: 4.0.0
+ */
+GArrowArray *
+ggandiva_selection_vector_to_array(GGandivaSelectionVector *selection_vector)
+{
+  auto gandiva_selection_vector =
+    ggandiva_selection_vector_get_raw(selection_vector);
+  auto arrow_array = gandiva_selection_vector->ToArray();
+  return garrow_array_new_raw(&arrow_array);
+}
+
+
+G_DEFINE_TYPE(GGandivaUInt16SelectionVector,
+              ggandiva_uint16_selection_vector,
+              GGANDIVA_TYPE_SELECTION_VECTOR)
+
+static void
+ggandiva_uint16_selection_vector_init(
+  GGandivaUInt16SelectionVector *selection_vector)
+{
+}
+
+static void
+ggandiva_uint16_selection_vector_class_init(
+  GGandivaUInt16SelectionVectorClass *klass)
+{
+}
+
+/**
+ * ggandiva_uint16_selection_vector_new:
+ * @max_slots: The max number of slots.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: A newly created #GGandivaUInt16SelectionVector.
+ *
+ * Since: 4.0.0
+ */
+GGandivaUInt16SelectionVector *
+ggandiva_uint16_selection_vector_new(gint64 max_slots,
+                                     GError **error)
+{
+  auto memory_pool = arrow::default_memory_pool();
+  std::shared_ptr<gandiva::SelectionVector> gandiva_selection_vector;
+  auto status = gandiva::SelectionVector::MakeInt16(max_slots,
+                                                    memory_pool,
+                                                    &gandiva_selection_vector);
+  if (garrow_error_check(error,
+                         status,
+                         "[gandiva][uint16-selection-vector][new]")) {
+    return GGANDIVA_UINT16_SELECTION_VECTOR(
+      ggandiva_selection_vector_new_raw(&gandiva_selection_vector));
+  } else {
+    return NULL;
+  }
+}
+
+
+G_DEFINE_TYPE(GGandivaUInt32SelectionVector,
+              ggandiva_uint32_selection_vector,
+              GGANDIVA_TYPE_SELECTION_VECTOR)
+
+static void
+ggandiva_uint32_selection_vector_init(
+  GGandivaUInt32SelectionVector *selection_vector)
+{
+}
+
+static void
+ggandiva_uint32_selection_vector_class_init(
+  GGandivaUInt32SelectionVectorClass *klass)
+{
+}
+
+/**
+ * ggandiva_uint32_selection_vector_new:
+ * @max_slots: The max number of slots.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: A newly created #GGandivaUInt32SelectionVector.
+ *
+ * Since: 4.0.0
+ */
+GGandivaUInt32SelectionVector *
+ggandiva_uint32_selection_vector_new(gint64 max_slots,
+                                     GError **error)
+{
+  auto memory_pool = arrow::default_memory_pool();
+  std::shared_ptr<gandiva::SelectionVector> gandiva_selection_vector;
+  auto status = gandiva::SelectionVector::MakeInt32(max_slots,
+                                                    memory_pool,
+                                                    &gandiva_selection_vector);
+  if (garrow_error_check(error,
+                         status,
+                         "[gandiva][uint32-selection-vector][new]")) {
+    return GGANDIVA_UINT32_SELECTION_VECTOR(
+      ggandiva_selection_vector_new_raw(&gandiva_selection_vector));
+  } else {
+    return NULL;
+  }
+}
+
+
+G_DEFINE_TYPE(GGandivaUInt64SelectionVector,
+              ggandiva_uint64_selection_vector,
+              GGANDIVA_TYPE_SELECTION_VECTOR)
+
+static void
+ggandiva_uint64_selection_vector_init(
+  GGandivaUInt64SelectionVector *selection_vector)
+{
+}
+
+static void
+ggandiva_uint64_selection_vector_class_init(
+  GGandivaUInt64SelectionVectorClass *klass)
+{
+}
+
+/**
+ * ggandiva_uint64_selection_vector_new:
+ * @max_slots: The max number of slots.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: A newly created #GGandivaUInt64SelectionVector.
+ *
+ * Since: 4.0.0
+ */
+GGandivaUInt64SelectionVector *
+ggandiva_uint64_selection_vector_new(gint64 max_slots,
+                                     GError **error)
+{
+  auto memory_pool = arrow::default_memory_pool();
+  std::shared_ptr<gandiva::SelectionVector> gandiva_selection_vector;
+  auto status = gandiva::SelectionVector::MakeInt64(max_slots,
+                                                    memory_pool,
+                                                    &gandiva_selection_vector);
+  if (garrow_error_check(error,
+                         status,
+                         "[gandiva][uint64-selection-vector][new]")) {
+    return GGANDIVA_UINT64_SELECTION_VECTOR(
+      ggandiva_selection_vector_new_raw(&gandiva_selection_vector));
+  } else {
+    return NULL;
+  }
+}
+
+
+G_END_DECLS
+
+
+GGandivaSelectionVector *
+ggandiva_selection_vector_new_raw(
+  std::shared_ptr<gandiva::SelectionVector> *gandiva_selection_vector)
+{
+  GType type = GGANDIVA_TYPE_SELECTION_VECTOR;
+  switch ((*gandiva_selection_vector)->GetMode()) {
+  case gandiva::SelectionVector::Mode::MODE_UINT16:
+    type = GGANDIVA_TYPE_UINT16_SELECTION_VECTOR;
+    break;
+  case gandiva::SelectionVector::Mode::MODE_UINT32:
+    type = GGANDIVA_TYPE_UINT32_SELECTION_VECTOR;
+    break;
+  case gandiva::SelectionVector::Mode::MODE_UINT64:
+    type = GGANDIVA_TYPE_UINT64_SELECTION_VECTOR;
+    break;
+  default:
+    break;
+  }
+  auto selection_vector =
+    g_object_new(type,
+                 "selection-vector", gandiva_selection_vector,
+                 NULL);
+  return GGANDIVA_SELECTION_VECTOR(selection_vector);
+}
+
+std::shared_ptr<gandiva::SelectionVector>
+ggandiva_selection_vector_get_raw(GGandivaSelectionVector *selection_vector)
+{
+  auto priv = GGANDIVA_SELECTION_VECTOR_GET_PRIVATE(selection_vector);
+  return priv->selection_vector;
+}
diff --git a/c_glib/gandiva-glib/selection-vector.h 
b/c_glib/gandiva-glib/selection-vector.h
new file mode 100644
index 0000000..029c4cd
--- /dev/null
+++ b/c_glib/gandiva-glib/selection-vector.h
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <arrow-glib/arrow-glib.h>
+
+#include <gandiva-glib/version.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GGandivaSelectionVectorMode:
+ * @GGANDIVA_SELECTION_VECTOR_MODE_NONE: Selection vector isn't used.
+ * @GGANDIVA_SELECTION_VECTOR_MODE_UINT16:
+ *   #GGandivaUInt16SelectionVector is used.
+ * @GGANDIVA_SELECTION_VECTOR_MODE_UINT32:
+ *   #GGandivaUInt32SelectionVector is used.
+ * @GGANDIVA_SELECTION_VECTOR_MODE_UINT64:
+ *   #GGandivaUInt64SelectionVector is used.
+ *
+ * They are corresponding to `gandiva::SelectionVector::Mode` values.
+ *
+ * Since: 4.0.0
+ */
+typedef enum {
+  GGANDIVA_SELECTION_VECTOR_MODE_NONE,
+  GGANDIVA_SELECTION_VECTOR_MODE_UINT16,
+  GGANDIVA_SELECTION_VECTOR_MODE_UINT32,
+  GGANDIVA_SELECTION_VECTOR_MODE_UINT64,
+} GGandivaSelectionVectorMode;
+
+
+#define GGANDIVA_TYPE_SELECTION_VECTOR (ggandiva_selection_vector_get_type())
+G_DECLARE_DERIVABLE_TYPE(GGandivaSelectionVector,
+                         ggandiva_selection_vector,
+                         GGANDIVA,
+                         SELECTION_VECTOR,
+                         GObject)
+
+struct _GGandivaSelectionVectorClass
+{
+  GObjectClass parent_class;
+};
+
+GGANDIVA_AVAILABLE_IN_4_0
+GGandivaSelectionVectorMode
+ggandiva_selection_vector_get_mode(GGandivaSelectionVector *selection_vector);
+
+GGANDIVA_AVAILABLE_IN_4_0
+GArrowArray *
+ggandiva_selection_vector_to_array(GGandivaSelectionVector *selection_vector);
+
+
+#define GGANDIVA_TYPE_UINT16_SELECTION_VECTOR   \
+  (ggandiva_uint16_selection_vector_get_type())
+G_DECLARE_DERIVABLE_TYPE(GGandivaUInt16SelectionVector,
+                         ggandiva_uint16_selection_vector,
+                         GGANDIVA,
+                         UINT16_SELECTION_VECTOR,
+                         GGandivaSelectionVector)
+
+struct _GGandivaUInt16SelectionVectorClass
+{
+  GGandivaSelectionVectorClass parent_class;
+};
+
+GGANDIVA_AVAILABLE_IN_4_0
+GGandivaUInt16SelectionVector *
+ggandiva_uint16_selection_vector_new(gint64 max_slots,
+                                     GError **error);
+
+
+#define GGANDIVA_TYPE_UINT32_SELECTION_VECTOR   \
+  (ggandiva_uint32_selection_vector_get_type())
+G_DECLARE_DERIVABLE_TYPE(GGandivaUInt32SelectionVector,
+                         ggandiva_uint32_selection_vector,
+                         GGANDIVA,
+                         UINT32_SELECTION_VECTOR,
+                         GGandivaSelectionVector)
+
+struct _GGandivaUInt32SelectionVectorClass
+{
+  GGandivaSelectionVectorClass parent_class;
+};
+
+GGANDIVA_AVAILABLE_IN_4_0
+GGandivaUInt32SelectionVector *
+ggandiva_uint32_selection_vector_new(gint64 max_slots,
+                                     GError **error);
+
+
+#define GGANDIVA_TYPE_UINT64_SELECTION_VECTOR   \
+  (ggandiva_uint64_selection_vector_get_type())
+G_DECLARE_DERIVABLE_TYPE(GGandivaUInt64SelectionVector,
+                         ggandiva_uint64_selection_vector,
+                         GGANDIVA,
+                         UINT64_SELECTION_VECTOR,
+                         GGandivaSelectionVector)
+
+struct _GGandivaUInt64SelectionVectorClass
+{
+  GGandivaSelectionVectorClass parent_class;
+};
+
+GGANDIVA_AVAILABLE_IN_4_0
+GGandivaUInt64SelectionVector *
+ggandiva_uint64_selection_vector_new(gint64 max_slots,
+                                     GError **error);
+
+
+G_END_DECLS
diff --git a/c_glib/gandiva-glib/projector.hpp 
b/c_glib/gandiva-glib/selection-vector.hpp
similarity index 71%
copy from c_glib/gandiva-glib/projector.hpp
copy to c_glib/gandiva-glib/selection-vector.hpp
index 1e9359b..aec5831 100644
--- a/c_glib/gandiva-glib/projector.hpp
+++ b/c_glib/gandiva-glib/selection-vector.hpp
@@ -21,9 +21,12 @@
 
 #include <memory>
 
-#include <gandiva/projector.h>
+#include <gandiva/selection_vector.h>
 
-#include <gandiva-glib/projector.h>
+#include <gandiva-glib/selection-vector.h>
 
-GGandivaProjector 
*ggandiva_projector_new_raw(std::shared_ptr<gandiva::Projector> 
*gandiva_projector);
-std::shared_ptr<gandiva::Projector> 
ggandiva_projector_get_raw(GGandivaProjector *projector);
+GGandivaSelectionVector *
+ggandiva_selection_vector_new_raw(
+  std::shared_ptr<gandiva::SelectionVector> *gandiva_selection_vector);
+std::shared_ptr<gandiva::SelectionVector>
+ggandiva_selection_vector_get_raw(GGandivaSelectionVector *selection_vector);
diff --git a/c_glib/gandiva-glib/version.h.in b/c_glib/gandiva-glib/version.h.in
index 85cfe6d..3c9e87c 100644
--- a/c_glib/gandiva-glib/version.h.in
+++ b/c_glib/gandiva-glib/version.h.in
@@ -120,6 +120,15 @@
 #define GGANDIVA_VERSION_1_0 G_ENCODE_VERSION(1, 0)
 
 /**
+ * GGANDIVA_VERSION_4_0:
+ *
+ * You can use this macro value for compile time API version check.
+ *
+ * Since: 4.0.0
+ */
+#define GGANDIVA_VERSION_4_0 G_ENCODE_VERSION(4, 0)
+
+/**
  * GGANDIVA_VERSION_MIN_REQUIRED:
  *
  * You can use this macro for compile time API version check.
@@ -166,6 +175,20 @@
 
 #define GGANDIVA_AVAILABLE_IN_ALL
 
+#if GGANDIVA_VERSION_MIN_REQUIRED >= GGANDIVA_VERSION_4_0
+#  define GGANDIVA_DEPRECATED_IN_4_0                GGANDIVA_DEPRECATED
+#  define GGANDIVA_DEPRECATED_IN_4_0_FOR(function)  
GGANDIVA_DEPRECATED_FOR(function)
+#else
+#  define GGANDIVA_DEPRECATED_IN_4_0
+#  define GGANDIVA_DEPRECATED_IN_4_0_FOR(function)
+#endif
+
+#if GGANDIVA_VERSION_MAX_ALLOWED < GGANDIVA_VERSION_4_0
+#  define GGANDIVA_AVAILABLE_IN_4_0 GGANDIVA_UNAVAILABLE(4, 0)
+#else
+#  define GGANDIVA_AVAILABLE_IN_4_0
+#endif
+
 #if GGANDIVA_VERSION_MIN_REQUIRED >= GGANDIVA_VERSION_1_0
 #  define GGANDIVA_DEPRECATED_IN_1_0                GGANDIVA_DEPRECATED
 #  define GGANDIVA_DEPRECATED_IN_1_0_FOR(function)  
GGANDIVA_DEPRECATED_FOR(function)
diff --git a/c_glib/test/gandiva/test-condition.rb 
b/c_glib/test/gandiva/test-condition.rb
new file mode 100644
index 0000000..51fb9f1
--- /dev/null
+++ b/c_glib/test/gandiva/test-condition.rb
@@ -0,0 +1,35 @@
+# 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.
+
+class TestGandivaCondition < Test::Unit::TestCase
+  def setup
+    omit("Gandiva is required") unless defined?(::Gandiva)
+    field1 = Arrow::Field.new("field1", Arrow::Int32DataType.new)
+    field2 = Arrow::Field.new("field2", Arrow::Int32DataType.new)
+    field1_node = Gandiva::FieldNode.new(field1)
+    field2_node = Gandiva::FieldNode.new(field2)
+    function_node = Gandiva::FunctionNode.new("equal",
+                                              [field1_node, field2_node],
+                                              Arrow::BooleanDataType.new)
+    @condition = Gandiva::Condition.new(function_node)
+  end
+
+  def test_to_s
+    assert_equal("bool equal((int32) field1, (int32) field2)",
+                 @condition.to_s)
+  end
+end
diff --git a/c_glib/test/gandiva/test-projector.rb 
b/c_glib/test/gandiva/test-filter.rb
similarity index 50%
copy from c_glib/test/gandiva/test-projector.rb
copy to c_glib/test/gandiva/test-filter.rb
index 4d33756..3da7774 100644
--- a/c_glib/test/gandiva/test-projector.rb
+++ b/c_glib/test/gandiva/test-filter.rb
@@ -15,42 +15,37 @@
 # specific language governing permissions and limitations
 # under the License.
 
-class TestGandivaProjector < Test::Unit::TestCase
+class TestGandivaFilter < Test::Unit::TestCase
   include Helper::Buildable
 
   def setup
     omit("Gandiva is required") unless defined?(::Gandiva)
-  end
 
-  def test_evaluate
     field1 = Arrow::Field.new("field1", Arrow::Int32DataType.new)
     field2 = Arrow::Field.new("field2", Arrow::Int32DataType.new)
     schema = Arrow::Schema.new([field1, field2])
     field_node1 = Gandiva::FieldNode.new(field1)
     field_node2 = Gandiva::FieldNode.new(field2)
-    add_function_node = Gandiva::FunctionNode.new("add",
-                                                  [field_node1, field_node2],
-                                                  Arrow::Int32DataType.new)
-    subtract_function_node = Gandiva::FunctionNode.new("subtract",
-                                                       [field_node1, 
field_node2],
-                                                       
Arrow::Int32DataType.new)
-    add_result = Arrow::Field.new("add_result", Arrow::Int32DataType.new)
-    add_expression = Gandiva::Expression.new(add_function_node, add_result)
-    subtract_result = Arrow::Field.new("subtract_result", 
Arrow::Int32DataType.new)
-    subtract_expression = Gandiva::Expression.new(subtract_function_node, 
subtract_result)
+    equal_function_node =
+      Gandiva::FunctionNode.new("equal",
+                                [field_node1, field_node2],
+                                Arrow::BooleanDataType.new)
+    condition = Gandiva::Condition.new(equal_function_node)
+    @filter = Gandiva::Filter.new(schema, condition)
 
-    projector = Gandiva::Projector.new(schema,
-                                       [add_expression, subtract_expression])
     input_arrays = [
       build_int32_array([1, 2, 3, 4]),
-      build_int32_array([11, 13, 15, 17]),
+      build_int32_array([11, 2, 15, 4]),
     ]
-    record_batch = Arrow::RecordBatch.new(schema, 4, input_arrays)
-    outputs = projector.evaluate(record_batch)
-    assert_equal([
-                   [12, 15, 18, 21],
-                   [-10, -11, -12, -13],
-                 ],
-                 outputs.collect(&:values))
+    @record_batch = Arrow::RecordBatch.new(schema,
+                                           input_arrays[0].length,
+                                           input_arrays)
+  end
+
+  def test_evaluate
+    selection_vector = Gandiva::UInt16SelectionVector.new(@record_batch.n_rows)
+    @filter.evaluate(@record_batch, selection_vector)
+    assert_equal(build_uint16_array([1, 3]),
+                 selection_vector.to_array)
   end
 end
diff --git a/c_glib/test/gandiva/test-projector.rb 
b/c_glib/test/gandiva/test-projector.rb
index 4d33756..308e1c3 100644
--- a/c_glib/test/gandiva/test-projector.rb
+++ b/c_glib/test/gandiva/test-projector.rb
@@ -20,33 +20,40 @@ class TestGandivaProjector < Test::Unit::TestCase
 
   def setup
     omit("Gandiva is required") unless defined?(::Gandiva)
-  end
 
-  def test_evaluate
     field1 = Arrow::Field.new("field1", Arrow::Int32DataType.new)
     field2 = Arrow::Field.new("field2", Arrow::Int32DataType.new)
-    schema = Arrow::Schema.new([field1, field2])
-    field_node1 = Gandiva::FieldNode.new(field1)
-    field_node2 = Gandiva::FieldNode.new(field2)
-    add_function_node = Gandiva::FunctionNode.new("add",
-                                                  [field_node1, field_node2],
-                                                  Arrow::Int32DataType.new)
-    subtract_function_node = Gandiva::FunctionNode.new("subtract",
-                                                       [field_node1, 
field_node2],
-                                                       
Arrow::Int32DataType.new)
+    @schema = Arrow::Schema.new([field1, field2])
+    @field_node1 = Gandiva::FieldNode.new(field1)
+    @field_node2 = Gandiva::FieldNode.new(field2)
+    add_function_node =
+      Gandiva::FunctionNode.new("add",
+                                [@field_node1, @field_node2],
+                                Arrow::Int32DataType.new)
+    subtract_function_node =
+      Gandiva::FunctionNode.new("subtract",
+                                [@field_node1, @field_node2],
+                                Arrow::Int32DataType.new)
     add_result = Arrow::Field.new("add_result", Arrow::Int32DataType.new)
     add_expression = Gandiva::Expression.new(add_function_node, add_result)
-    subtract_result = Arrow::Field.new("subtract_result", 
Arrow::Int32DataType.new)
-    subtract_expression = Gandiva::Expression.new(subtract_function_node, 
subtract_result)
+    subtract_result = Arrow::Field.new("subtract_result",
+                                       Arrow::Int32DataType.new)
+    subtract_expression = Gandiva::Expression.new(subtract_function_node,
+                                                  subtract_result)
+    @projector = Gandiva::Projector.new(@schema,
+                                        [add_expression, subtract_expression])
 
-    projector = Gandiva::Projector.new(schema,
-                                       [add_expression, subtract_expression])
     input_arrays = [
       build_int32_array([1, 2, 3, 4]),
       build_int32_array([11, 13, 15, 17]),
     ]
-    record_batch = Arrow::RecordBatch.new(schema, 4, input_arrays)
-    outputs = projector.evaluate(record_batch)
+    @record_batch = Arrow::RecordBatch.new(@schema,
+                                           input_arrays[0].length,
+                                           input_arrays)
+  end
+
+  def test_evaluate
+    outputs = @projector.evaluate(@record_batch)
     assert_equal([
                    [12, 15, 18, 21],
                    [-10, -11, -12, -13],
diff --git a/c_glib/test/gandiva/test-selectable-projector.rb 
b/c_glib/test/gandiva/test-selectable-projector.rb
new file mode 100644
index 0000000..47b0059
--- /dev/null
+++ b/c_glib/test/gandiva/test-selectable-projector.rb
@@ -0,0 +1,74 @@
+# 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.
+
+class TestGandivaSelectableProjector < Test::Unit::TestCase
+  include Helper::Buildable
+
+  def setup
+    omit("Gandiva is required") unless defined?(::Gandiva)
+
+    field1 = Arrow::Field.new("field1", Arrow::Int32DataType.new)
+    field2 = Arrow::Field.new("field2", Arrow::Int32DataType.new)
+    @schema = Arrow::Schema.new([field1, field2])
+
+    input_arrays = [
+      build_int32_array([1, 2, 3, 4]),
+      build_int32_array([11, 13, 15, 17]),
+    ]
+    @record_batch = Arrow::RecordBatch.new(@schema,
+                                           input_arrays[0].length,
+                                           input_arrays)
+
+    @field_node1 = Gandiva::FieldNode.new(field1)
+    @field_node2 = Gandiva::FieldNode.new(field2)
+    add_function_node =
+      Gandiva::FunctionNode.new("add",
+                                [@field_node1, @field_node2],
+                                Arrow::Int32DataType.new)
+    subtract_function_node =
+      Gandiva::FunctionNode.new("subtract",
+                                [@field_node1, @field_node2],
+                                Arrow::Int32DataType.new)
+    add_result = Arrow::Field.new("add_result", Arrow::Int32DataType.new)
+    add_expression = Gandiva::Expression.new(add_function_node, add_result)
+    subtract_result = Arrow::Field.new("subtract_result",
+                                       Arrow::Int32DataType.new)
+    subtract_expression = Gandiva::Expression.new(subtract_function_node,
+                                                  subtract_result)
+    @selection_vector = 
Gandiva::UInt16SelectionVector.new(@record_batch.n_rows)
+    @projector =
+      Gandiva::SelectableProjector.new(@schema,
+                                       [add_expression, subtract_expression],
+                                       @selection_vector.mode)
+  end
+
+  def test_evaluate
+    two_node = Gandiva::Int32LiteralNode.new(2)
+    condition_node = Gandiva::FunctionNode.new("greater_than",
+                                               [@field_node1, two_node],
+                                               Arrow::BooleanDataType.new)
+    condition = Gandiva::Condition.new(condition_node)
+    filter = Gandiva::Filter.new(@schema, condition)
+    filter.evaluate(@record_batch, @selection_vector)
+    outputs = @projector.evaluate(@record_batch, @selection_vector)
+    assert_equal([
+                   [18, 21],
+                   [-12, -13],
+                 ],
+                 outputs.collect(&:values))
+  end
+end
diff --git a/c_glib/test/gandiva/test-selection-vector.rb 
b/c_glib/test/gandiva/test-selection-vector.rb
new file mode 100644
index 0000000..ca5042c
--- /dev/null
+++ b/c_glib/test/gandiva/test-selection-vector.rb
@@ -0,0 +1,42 @@
+# 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.
+
+class TestGandivaSelectionVector < Test::Unit::TestCase
+  include Helper::Buildable
+
+  def setup
+    omit("Gandiva is required") unless defined?(::Gandiva)
+  end
+
+  def test_uint16
+    selection_vector = Gandiva::UInt16SelectionVector.new(10)
+    assert_equal(build_uint16_array([]),
+                 selection_vector.to_array)
+  end
+
+  def test_uint32
+    selection_vector = Gandiva::UInt32SelectionVector.new(10)
+    assert_equal(build_uint32_array([]),
+                 selection_vector.to_array)
+  end
+
+  def test_uint64
+    selection_vector = Gandiva::UInt64SelectionVector.new(10)
+    assert_equal(build_uint64_array([]),
+                 selection_vector.to_array)
+  end
+end

Reply via email to