Skip to content

Commit

Permalink
ARROW-7201: [GLib][Gandiva] Add support for BooleanNode
Browse files Browse the repository at this point in the history
The following Nodes is added as a child class of GGandivaBooleanNode.
- GGandivaAndNode
- GGandivaOrNode

Closes #6389 from shiro615/glib-gandiva-boolean-node and squashes the following commits:

5e137fd <Sutou Kouhei> Enable Gandiva on macOS
31ec7d8 <Sutou Kouhei> Fix a typo
0a890ea <Sutou Kouhei> Fix parameter name
92f5d3d <Sutou Kouhei> Fix parent class
c626d36 <Sutou Kouhei> Use g_list_copy_deep()
f4a7422 <Sutou Kouhei> Make lower
23bd33f <Yosuke Shiro> Add version macros
c2dff33 <Yosuke Shiro> Define ggandiva_boolean_node_new_raw()
461dc8c <Yosuke Shiro> Define ggandiva_boolean_node_get_children()
08e270a <Yosuke Shiro> Use children instead of parameters
21203bb <Yosuke Shiro> Use g_list_free_full()
09c904a <Yosuke Shiro> ARROW-7201:  Add support for BooleanNode

Lead-authored-by: Yosuke Shiro <yosuke.shiro615@gmail.com>
Co-authored-by: Sutou Kouhei <kou@clear-code.com>
Signed-off-by: Sutou Kouhei <kou@clear-code.com>
  • Loading branch information
shiro615 and kou committed Feb 19, 2020
1 parent 18b9167 commit 45d7eaf
Show file tree
Hide file tree
Showing 6 changed files with 254 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ruby.yml
Expand Up @@ -80,6 +80,7 @@ jobs:
fail-fast: false
env:
ARROW_BUILD_TESTS: ON
ARROW_GANDIVA: ON
ARROW_GLIB_DEVELOPMENT_MODE: true
ARROW_GLIB_GTK_DOC: true
ARROW_HOME: /usr/local
Expand Down
2 changes: 2 additions & 0 deletions c_glib/gandiva-glib/gandiva-glib.h
Expand Up @@ -19,6 +19,8 @@

#pragma once

#include <gandiva-glib/version.h>

#include <gandiva-glib/expression.h>
#include <gandiva-glib/function-registry.h>
#include <gandiva-glib/function-signature.h>
Expand Down
159 changes: 159 additions & 0 deletions c_glib/gandiva-glib/node.cpp
Expand Up @@ -97,6 +97,12 @@ G_BEGIN_DECLS
*
* #GGandivaIfNode is a class for a node in the expression tree, representing an if-else.
*
* #GGandivaBooleanNode is a class for a node in the expression tree, representing a boolean.
*
* #GGandivaAndNode is a class for a node in the expression tree, representing an AND.
*
* #GGandivaOrNode is a class for a node in the expression tree, representing an OR.
*
* Since: 0.12.0
*/

Expand Down Expand Up @@ -1387,6 +1393,136 @@ ggandiva_if_node_new(GGandivaNode *condition_node,
return_type);
}


typedef struct GGandivaBooleanNodePrivate_ {
GList *children;
} GGandivaBooleanNodePrivate;

G_DEFINE_TYPE_WITH_PRIVATE(GGandivaBooleanNode,
ggandiva_boolean_node,
GGANDIVA_TYPE_NODE)

#define GGANDIVA_BOOLEAN_NODE_GET_PRIVATE(object) \
static_cast<GGandivaBooleanNodePrivate *>( \
ggandiva_boolean_node_get_instance_private( \
GGANDIVA_BOOLEAN_NODE(object))) \

static void
ggandiva_boolean_node_dispose(GObject *object)
{
auto priv = GGANDIVA_BOOLEAN_NODE_GET_PRIVATE(object);

if (priv->children) {
g_list_free_full(priv->children, g_object_unref);
priv->children = nullptr;
}

G_OBJECT_CLASS(ggandiva_boolean_node_parent_class)->dispose(object);
}

static void
ggandiva_boolean_node_init(GGandivaBooleanNode *boolean_node)
{
auto priv = GGANDIVA_BOOLEAN_NODE_GET_PRIVATE(boolean_node);
priv->children = nullptr;
}

static void
ggandiva_boolean_node_class_init(GGandivaBooleanNodeClass *klass)
{
auto gobject_class = G_OBJECT_CLASS(klass);

gobject_class->dispose = ggandiva_boolean_node_dispose;
}

/**
* ggandiva_boolean_node_get_children:
* @node: A #GGandivaBooleanNode.
*
* Returns: (transfer none) (element-type GGandivaNode):
* The children of the boolean node.
*
* Since: 1.0.0
*/
GList *
ggandiva_boolean_node_get_children(GGandivaBooleanNode *node)
{
auto priv = GGANDIVA_BOOLEAN_NODE_GET_PRIVATE(node);
return priv->children;
}


G_DEFINE_TYPE(GGandivaAndNode,
ggandiva_and_node,
GGANDIVA_TYPE_BOOLEAN_NODE)

static void
ggandiva_and_node_init(GGandivaAndNode *and_node)
{
}

static void
ggandiva_and_node_class_init(GGandivaAndNodeClass *klass)
{
}

/**
* ggandiva_and_node_new:
* @children: (element-type GGandivaNode): The children of the AND node.
*
* Returns: A newly created #GGandivaAndNode for the AND expression.
*
* Since: 1.0.0
*/
GGandivaAndNode *
ggandiva_and_node_new(GList *children)
{
std::vector<std::shared_ptr<gandiva::Node>> gandiva_nodes;
for (auto node = children; node; node = g_list_next(node)) {
auto gandiva_node = ggandiva_node_get_raw(GGANDIVA_NODE(node->data));
gandiva_nodes.push_back(gandiva_node);
}
auto gandiva_node = gandiva::TreeExprBuilder::MakeAnd(gandiva_nodes);
return GGANDIVA_AND_NODE(ggandiva_boolean_node_new_raw(&gandiva_node,
children));
}


G_DEFINE_TYPE(GGandivaOrNode,
ggandiva_or_node,
GGANDIVA_TYPE_BOOLEAN_NODE)

static void
ggandiva_or_node_init(GGandivaOrNode *or_node)
{
}

static void
ggandiva_or_node_class_init(GGandivaOrNodeClass *klass)
{
}

/**
* ggandiva_or_node_new:
* @children: (element-type GGandivaNode): The children of the OR node.
*
* Returns: A newly created #GGandivaOrNode for the OR expression.
*
* Since: 1.0.0
*/
GGandivaOrNode *
ggandiva_or_node_new(GList *children)
{
std::vector<std::shared_ptr<gandiva::Node>> gandiva_nodes;
for (auto node = children; node; node = g_list_next(node)) {
auto gandiva_node = ggandiva_node_get_raw(GGANDIVA_NODE(node->data));
gandiva_nodes.push_back(gandiva_node);
}
auto gandiva_node = gandiva::TreeExprBuilder::MakeOr(gandiva_nodes);
return GGANDIVA_OR_NODE(ggandiva_boolean_node_new_raw(&gandiva_node,
children));
}

G_END_DECLS

std::shared_ptr<gandiva::Node>
Expand Down Expand Up @@ -1529,3 +1665,26 @@ ggandiva_if_node_new_raw(std::shared_ptr<gandiva::Node> *gandiva_node,
NULL);
return GGANDIVA_IF_NODE(if_node);
}

GGandivaBooleanNode *
ggandiva_boolean_node_new_raw(std::shared_ptr<gandiva::Node> *gandiva_node,
GList *children)
{
auto gandiva_boolean_node =
std::static_pointer_cast<gandiva::BooleanNode>(*gandiva_node);

GType type;
if (gandiva_boolean_node->expr_type() == gandiva::BooleanNode::AND) {
type = GGANDIVA_TYPE_AND_NODE;
} else {
type = GGANDIVA_TYPE_OR_NODE;
}
auto boolean_node = g_object_new(type,
"node", gandiva_node,
NULL);
auto priv = GGANDIVA_BOOLEAN_NODE_GET_PRIVATE(boolean_node);
priv->children = g_list_copy_deep(children,
reinterpret_cast<GCopyFunc>(g_object_ref),
NULL);
return GGANDIVA_BOOLEAN_NODE(boolean_node);
}
51 changes: 51 additions & 0 deletions c_glib/gandiva-glib/node.h
Expand Up @@ -21,6 +21,8 @@

#include <arrow-glib/arrow-glib.h>

#include <gandiva-glib/version.h>

G_BEGIN_DECLS

#define GGANDIVA_TYPE_NODE (ggandiva_node_get_type())
Expand Down Expand Up @@ -341,4 +343,53 @@ ggandiva_if_node_new(GGandivaNode *condition_node,
GArrowDataType *return_type,
GError **error);


#define GGANDIVA_TYPE_BOOLEAN_NODE (ggandiva_boolean_node_get_type())
G_DECLARE_DERIVABLE_TYPE(GGandivaBooleanNode,
ggandiva_boolean_node,
GGANDIVA,
BOOLEAN_NODE,
GGandivaNode)

struct _GGandivaBooleanNodeClass
{
GGandivaNodeClass parent_class;
};

GGANDIVA_AVAILABLE_IN_1_0
GList *
ggandiva_boolean_node_get_children(GGandivaBooleanNode *node);


#define GGANDIVA_TYPE_AND_NODE (ggandiva_and_node_get_type())
G_DECLARE_DERIVABLE_TYPE(GGandivaAndNode,
ggandiva_and_node,
GGANDIVA,
AND_NODE,
GGandivaBooleanNode)
struct _GGandivaAndNodeClass
{
GGandivaBooleanNodeClass parent_class;
};

GGANDIVA_AVAILABLE_IN_1_0
GGandivaAndNode *
ggandiva_and_node_new(GList *children);


#define GGANDIVA_TYPE_OR_NODE (ggandiva_or_node_get_type())
G_DECLARE_DERIVABLE_TYPE(GGandivaOrNode,
ggandiva_or_node,
GGANDIVA,
OR_NODE,
GGandivaBooleanNode)
struct _GGandivaOrNodeClass
{
GGandivaBooleanNodeClass parent_class;
};

GGANDIVA_AVAILABLE_IN_1_0
GGandivaOrNode *
ggandiva_or_node_new(GList *children);

G_END_DECLS
3 changes: 3 additions & 0 deletions c_glib/gandiva-glib/node.hpp
Expand Up @@ -44,3 +44,6 @@ ggandiva_if_node_new_raw(std::shared_ptr<gandiva::Node> *gandiva_node,
GGandivaNode *then_node,
GGandivaNode *else_node,
GArrowDataType *return_type);
GGandivaBooleanNode *
ggandiva_boolean_node_new_raw(std::shared_ptr<gandiva::Node> *gandiva_node,
GList *children);
38 changes: 38 additions & 0 deletions c_glib/test/gandiva/test-boolean-node.rb
@@ -0,0 +1,38 @@
# 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 TestGandivaBooleanNode < 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)
end

def test_and
and_node = Gandiva::AndNode.new([@field1_node, @field2_node])
assert_equal([@field1_node, @field2_node],
and_node.children)
end

def test_or
or_node = Gandiva::OrNode.new([@field1_node, @field2_node])
assert_equal([@field1_node, @field2_node],
or_node.children)
end
end

0 comments on commit 45d7eaf

Please sign in to comment.