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 0059d61 ARROW-14335: [GLib][Ruby] Add support for expression
0059d61 is described below
commit 0059d6113ac1ab0db13733ea99ef0987c0a598a2
Author: Sutou Kouhei <[email protected]>
AuthorDate: Fri Oct 15 14:51:32 2021 +0900
ARROW-14335: [GLib][Ruby] Add support for expression
Closes #11429 from kou/glib-expression
Authored-by: Sutou Kouhei <[email protected]>
Signed-off-by: Sutou Kouhei <[email protected]>
---
c_glib/arrow-glib/arrow-glib.h | 1 +
c_glib/arrow-glib/arrow-glib.hpp | 2 +
c_glib/arrow-glib/expression.cpp | 265 ++++++++++++++++++++++++++++++
c_glib/arrow-glib/expression.h | 96 +++++++++++
c_glib/arrow-glib/expression.hpp | 30 ++++
c_glib/arrow-glib/meson.build | 3 +
c_glib/doc/arrow-glib/arrow-glib-docs.xml | 1 +
c_glib/test/test-call-expression.rb | 42 +++++
c_glib/test/test-field-expression.rb | 49 ++++++
c_glib/test/test-literal-expression.rb | 40 +++++
ruby/red-arrow/lib/arrow/expression.rb | 48 ++++++
ruby/red-arrow/lib/arrow/loader.rb | 1 +
ruby/red-arrow/test/test-expression.rb | 40 +++++
13 files changed, 618 insertions(+)
diff --git a/c_glib/arrow-glib/arrow-glib.h b/c_glib/arrow-glib/arrow-glib.h
index e25044e..57a3508 100644
--- a/c_glib/arrow-glib/arrow-glib.h
+++ b/c_glib/arrow-glib/arrow-glib.h
@@ -31,6 +31,7 @@
#include <arrow-glib/datum.h>
#include <arrow-glib/enums.h>
#include <arrow-glib/error.h>
+#include <arrow-glib/expression.h>
#include <arrow-glib/field.h>
#include <arrow-glib/record-batch.h>
#include <arrow-glib/scalar.h>
diff --git a/c_glib/arrow-glib/arrow-glib.hpp b/c_glib/arrow-glib/arrow-glib.hpp
index 6dc6d43..621c474 100644
--- a/c_glib/arrow-glib/arrow-glib.hpp
+++ b/c_glib/arrow-glib/arrow-glib.hpp
@@ -26,9 +26,11 @@
#include <arrow-glib/buffer.hpp>
#include <arrow-glib/chunked-array.hpp>
#include <arrow-glib/codec.hpp>
+#include <arrow-glib/compute.hpp>
#include <arrow-glib/data-type.hpp>
#include <arrow-glib/datum.hpp>
#include <arrow-glib/error.hpp>
+#include <arrow-glib/expression.hpp>
#include <arrow-glib/field.hpp>
#include <arrow-glib/record-batch.hpp>
#include <arrow-glib/scalar.hpp>
diff --git a/c_glib/arrow-glib/expression.cpp b/c_glib/arrow-glib/expression.cpp
new file mode 100644
index 0000000..406e121
--- /dev/null
+++ b/c_glib/arrow-glib/expression.cpp
@@ -0,0 +1,265 @@
+/*
+ * 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.
+ */
+
+#include <arrow-glib/compute.hpp>
+#include <arrow-glib/datum.hpp>
+#include <arrow-glib/expression.hpp>
+#include <arrow-glib/error.hpp>
+
+G_BEGIN_DECLS
+
+/**
+ * SECTION: expression
+ * @section_id: expression
+ * @title: Expression
+ * @include: arrow-glib/arrow-glib.h
+ *
+ * #GArrowExpression is a base class for all expression classes such
+ * as #GArrowLiteralExpression.
+ *
+ * #GArrowLiteralExpression is a class for literal value.
+ *
+ * #GArrowFieldExpression is a class for field reference.
+ *
+ * #GArrowCallExpression is a class for function call.
+ *
+ * Since: 6.0.0
+ */
+
+typedef struct GArrowExpressionPrivate_ {
+ arrow::compute::Expression expression;
+} GArrowExpressionPrivate;
+
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(GArrowExpression,
+ garrow_expression,
+ G_TYPE_OBJECT)
+
+#define GARROW_EXPRESSION_GET_PRIVATE(object) \
+ static_cast<GArrowExpressionPrivate *>( \
+ garrow_expression_get_instance_private( \
+ GARROW_EXPRESSION(object)))
+
+static void
+garrow_expression_finalize(GObject *object)
+{
+ auto priv = GARROW_EXPRESSION_GET_PRIVATE(object);
+ priv->expression.~Expression();
+ G_OBJECT_CLASS(garrow_expression_parent_class)->finalize(object);
+}
+
+static void
+garrow_expression_init(GArrowExpression *object)
+{
+ auto priv = GARROW_EXPRESSION_GET_PRIVATE(object);
+ new(&priv->expression) arrow::compute::Expression();
+}
+
+static void
+garrow_expression_class_init(GArrowExpressionClass *klass)
+{
+ auto gobject_class = G_OBJECT_CLASS(klass);
+
+ gobject_class->finalize = garrow_expression_finalize;
+}
+
+/**
+ * garrow_expression_to_string:
+ * @expression: A #GArrowExpression.
+ *
+ * Returns: The formatted expression.
+ *
+ * It should be freed with g_free() when no longer needed.
+ *
+ * Since: 6.0.0
+ */
+gchar *
+garrow_expression_to_string(GArrowExpression *expression)
+{
+ auto priv = GARROW_EXPRESSION_GET_PRIVATE(expression);
+ auto string = priv->expression.ToString();
+ return g_strndup(string.data(), string.size());
+}
+
+/**
+ * garrow_expression_equal:
+ * @expression: A #GArrowExpression.
+ * @other_expression: A #GArrowExpression.
+ *
+ * Returns: %TRUE if both of them have the same content, %FALSE
+ * otherwise.
+ *
+ * Since: 6.0.0
+ */
+gboolean
+garrow_expression_equal(GArrowExpression *expression,
+ GArrowExpression *other_expression)
+{
+ auto priv = GARROW_EXPRESSION_GET_PRIVATE(expression);
+ auto other_priv = GARROW_EXPRESSION_GET_PRIVATE(other_expression);
+ return priv->expression.Equals(other_priv->expression);
+}
+
+
+G_DEFINE_TYPE(GArrowLiteralExpression,
+ garrow_literal_expression,
+ GARROW_TYPE_EXPRESSION)
+
+static void
+garrow_literal_expression_init(GArrowLiteralExpression *object)
+{
+}
+
+static void
+garrow_literal_expression_class_init(GArrowLiteralExpressionClass *klass)
+{
+}
+
+/**
+ * garrow_literal_expression_new:
+ * @datum: A #GArrowDatum.
+ *
+ * Returns: A newly created #GArrowLiteralExpression.
+ *
+ * Since: 6.0.0
+ */
+GArrowLiteralExpression *
+garrow_literal_expression_new(GArrowDatum *datum)
+{
+ auto arrow_datum = garrow_datum_get_raw(datum);
+ auto arrow_expression = arrow::compute::literal(arrow_datum);
+ return
GARROW_LITERAL_EXPRESSION(garrow_expression_new_raw(arrow_expression));
+}
+
+
+G_DEFINE_TYPE(GArrowFieldExpression,
+ garrow_field_expression,
+ GARROW_TYPE_EXPRESSION)
+
+static void
+garrow_field_expression_init(GArrowFieldExpression *object)
+{
+}
+
+static void
+garrow_field_expression_class_init(GArrowFieldExpressionClass *klass)
+{
+}
+
+/**
+ * garrow_field_expression_new:
+ * @reference: A field name or dot path.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: A newly created #GArrowFieldExpression on sucess, %NULL on
+ * error.
+ *
+ * Since: 6.0.0
+ */
+GArrowFieldExpression *
+garrow_field_expression_new(const gchar *reference,
+ GError **error)
+{
+ if (reference && reference[0] == '.') {
+ auto arrow_reference_result = arrow::FieldRef::FromDotPath(reference);
+ if (!garrow::check(error,
+ arrow_reference_result,
+ "[field-expression][new]")) {
+ return NULL;
+ }
+ auto arrow_expression = arrow::compute::field_ref(*arrow_reference_result);
+ return
GARROW_FIELD_EXPRESSION(garrow_expression_new_raw(arrow_expression));
+ } else {
+ arrow::FieldRef arrow_reference(reference);
+ auto arrow_expression = arrow::compute::field_ref(arrow_reference);
+ return
GARROW_FIELD_EXPRESSION(garrow_expression_new_raw(arrow_expression));
+ }
+}
+
+
+G_DEFINE_TYPE(GArrowCallExpression,
+ garrow_call_expression,
+ GARROW_TYPE_EXPRESSION)
+
+static void
+garrow_call_expression_init(GArrowCallExpression *object)
+{
+}
+
+static void
+garrow_call_expression_class_init(GArrowCallExpressionClass *klass)
+{
+}
+
+/**
+ * garrow_call_expression_new:
+ * @function: A name of function to be called.
+ * @arguments: (element-type GArrowExpression): Arguments of this call.
+ * @options: (nullable): A #GArrowFunctionOptions for the called function.
+ *
+ * Returns: A newly created #GArrowCallExpression.
+ *
+ * Since: 6.0.0
+ */
+GArrowCallExpression *
+garrow_call_expression_new(const gchar *function,
+ GList *arguments,
+ GArrowFunctionOptions *options)
+{
+ std::vector<arrow::compute::Expression> arrow_arguments;
+ for (GList *node = arguments; node; node = node->next) {
+ auto argument = GARROW_EXPRESSION(node->data);
+ auto arrow_argument = garrow_expression_get_raw(argument);
+ arrow_arguments.push_back(*arrow_argument);
+ }
+ std::shared_ptr<arrow::compute::FunctionOptions> arrow_options;
+ if (options) {
+ arrow_options.reset(garrow_function_options_get_raw(options));
+ }
+ auto arrow_expression = arrow::compute::call(function,
+ arrow_arguments,
+ arrow_options);
+ return GARROW_CALL_EXPRESSION(garrow_expression_new_raw(arrow_expression));
+}
+
+
+G_END_DECLS
+
+GArrowExpression *
+garrow_expression_new_raw(const arrow::compute::Expression &arrow_expression)
+{
+ GType gtype = GARROW_TYPE_EXPRESSION;
+ if (arrow_expression.literal()) {
+ gtype = GARROW_TYPE_LITERAL_EXPRESSION;
+ } else if (arrow_expression.parameter()) {
+ gtype = GARROW_TYPE_FIELD_EXPRESSION;
+ } else if (arrow_expression.call()) {
+ gtype = GARROW_TYPE_CALL_EXPRESSION;
+ }
+ auto expression = GARROW_EXPRESSION(g_object_new(gtype, NULL));
+ auto priv = GARROW_EXPRESSION_GET_PRIVATE(expression);
+ priv->expression = arrow_expression;
+ return expression;
+}
+
+arrow::compute::Expression *
+garrow_expression_get_raw(GArrowExpression *expression)
+{
+ auto priv = GARROW_EXPRESSION_GET_PRIVATE(expression);
+ return &(priv->expression);
+}
diff --git a/c_glib/arrow-glib/expression.h b/c_glib/arrow-glib/expression.h
new file mode 100644
index 0000000..1c1a5fb
--- /dev/null
+++ b/c_glib/arrow-glib/expression.h
@@ -0,0 +1,96 @@
+/*
+ * 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/compute.h>
+
+G_BEGIN_DECLS
+
+#define GARROW_TYPE_EXPRESSION (garrow_expression_get_type())
+G_DECLARE_DERIVABLE_TYPE(GArrowExpression,
+ garrow_expression,
+ GARROW,
+ EXPRESSION,
+ GObject)
+struct _GArrowExpressionClass
+{
+ GObjectClass parent_class;
+};
+
+GARROW_AVAILABLE_IN_6_0
+gchar *
+garrow_expression_to_string(GArrowExpression *expression);
+GARROW_AVAILABLE_IN_6_0
+gboolean
+garrow_expression_equal(GArrowExpression *expression,
+ GArrowExpression *other_expression);
+
+
+#define GARROW_TYPE_LITERAL_EXPRESSION (garrow_literal_expression_get_type())
+G_DECLARE_DERIVABLE_TYPE(GArrowLiteralExpression,
+ garrow_literal_expression,
+ GARROW,
+ LITERAL_EXPRESSION,
+ GArrowExpression)
+struct _GArrowLiteralExpressionClass
+{
+ GArrowExpressionClass parent_class;
+};
+
+GARROW_AVAILABLE_IN_6_0
+GArrowLiteralExpression *
+garrow_literal_expression_new(GArrowDatum *datum);
+
+
+#define GARROW_TYPE_FIELD_EXPRESSION (garrow_field_expression_get_type())
+G_DECLARE_DERIVABLE_TYPE(GArrowFieldExpression,
+ garrow_field_expression,
+ GARROW,
+ FIELD_EXPRESSION,
+ GArrowExpression)
+struct _GArrowFieldExpressionClass
+{
+ GArrowExpressionClass parent_class;
+};
+
+GARROW_AVAILABLE_IN_6_0
+GArrowFieldExpression *
+garrow_field_expression_new(const gchar *reference,
+ GError **error);
+
+
+#define GARROW_TYPE_CALL_EXPRESSION (garrow_call_expression_get_type())
+G_DECLARE_DERIVABLE_TYPE(GArrowCallExpression,
+ garrow_call_expression,
+ GARROW,
+ CALL_EXPRESSION,
+ GArrowExpression)
+struct _GArrowCallExpressionClass
+{
+ GArrowExpressionClass parent_class;
+};
+
+GARROW_AVAILABLE_IN_6_0
+GArrowCallExpression *
+garrow_call_expression_new(const gchar *function,
+ GList *arguments,
+ GArrowFunctionOptions *options);
+
+G_END_DECLS
diff --git a/c_glib/arrow-glib/expression.hpp b/c_glib/arrow-glib/expression.hpp
new file mode 100644
index 0000000..ea872bb
--- /dev/null
+++ b/c_glib/arrow-glib/expression.hpp
@@ -0,0 +1,30 @@
+/*
+ * 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/compute/exec/expression.h>
+
+#include <arrow-glib/expression.h>
+
+
+GArrowExpression *
+garrow_expression_new_raw(const arrow::compute::Expression &arrow_expression);
+arrow::compute::Expression *
+garrow_expression_get_raw(GArrowExpression *expression);
diff --git a/c_glib/arrow-glib/meson.build b/c_glib/arrow-glib/meson.build
index d047963..9a399c9 100644
--- a/c_glib/arrow-glib/meson.build
+++ b/c_glib/arrow-glib/meson.build
@@ -29,6 +29,7 @@ sources = files(
'datum.cpp',
'decimal.cpp',
'error.cpp',
+ 'expression.cpp',
'field.cpp',
'record-batch.cpp',
'scalar.cpp',
@@ -86,6 +87,7 @@ c_headers = files(
'datum.h',
'decimal.h',
'error.h',
+ 'expression.h',
'field.h',
'gobject-type.h',
'record-batch.h',
@@ -144,6 +146,7 @@ cpp_headers = files(
'datum.hpp',
'decimal.hpp',
'error.hpp',
+ 'expression.hpp',
'field.hpp',
'record-batch.hpp',
'scalar.hpp',
diff --git a/c_glib/doc/arrow-glib/arrow-glib-docs.xml
b/c_glib/doc/arrow-glib/arrow-glib-docs.xml
index 4c061c0..43f6a7e 100644
--- a/c_glib/doc/arrow-glib/arrow-glib-docs.xml
+++ b/c_glib/doc/arrow-glib/arrow-glib-docs.xml
@@ -84,6 +84,7 @@
<title>Computation</title>
<xi:include href="xml/compute.xml"/>
<xi:include href="xml/datum.xml"/>
+ <xi:include href="xml/expression.xml"/>
</chapter>
<chapter id="buffer">
<title>Buffer</title>
diff --git a/c_glib/test/test-call-expression.rb
b/c_glib/test/test-call-expression.rb
new file mode 100644
index 0000000..a8ba2f4
--- /dev/null
+++ b/c_glib/test/test-call-expression.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 TestCallExpression < Test::Unit::TestCase
+ def setup
+ @arguments = [
+ Arrow::FieldExpression.new("augend"),
+ Arrow::FieldExpression.new("addend"),
+ ]
+ @expression = Arrow::CallExpression.new("add", @arguments)
+ end
+
+ sub_test_case("==") do
+ def test_true
+ assert_equal(Arrow::CallExpression.new("now", []),
+ Arrow::CallExpression.new("now", []))
+ end
+
+ def test_false
+ assert_not_equal(Arrow::CallExpression.new("a", []),
+ Arrow::CallExpression.new("b", []))
+ end
+ end
+
+ def test_to_string
+ assert_equal("add(augend, addend)", @expression.to_s)
+ end
+end
diff --git a/c_glib/test/test-field-expression.rb
b/c_glib/test/test-field-expression.rb
new file mode 100644
index 0000000..cdcfab7
--- /dev/null
+++ b/c_glib/test/test-field-expression.rb
@@ -0,0 +1,49 @@
+# 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 TestFieldExpression < Test::Unit::TestCase
+ def setup
+ @expression = Arrow::FieldExpression.new("visible")
+ end
+
+ sub_test_case("#initialize") do
+ def test_invalid_dot_path
+ message =
+ "[field-expression][new]: Invalid: " +
+ "Dot path '.[' contained an unterminated index"
+ assert_raise(Arrow::Error::Invalid.new(message)) do
+ Arrow::FieldExpression.new(".[")
+ end
+ end
+ end
+
+ sub_test_case("==") do
+ def test_true
+ assert_equal(Arrow::FieldExpression.new("visible"),
+ Arrow::FieldExpression.new(".visible"))
+ end
+
+ def test_false
+ assert_not_equal(@expression,
+ Arrow::FieldExpression.new("equal"))
+ end
+ end
+
+ def test_to_string
+ assert_equal("visible", @expression.to_s)
+ end
+end
diff --git a/c_glib/test/test-literal-expression.rb
b/c_glib/test/test-literal-expression.rb
new file mode 100644
index 0000000..7a8796f
--- /dev/null
+++ b/c_glib/test/test-literal-expression.rb
@@ -0,0 +1,40 @@
+# 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 TestLiteralExpression < Test::Unit::TestCase
+ def setup
+ @scalar = Arrow::BooleanScalar.new(true)
+ @datum = Arrow::ScalarDatum.new(@scalar)
+ @expression = Arrow::LiteralExpression.new(@datum)
+ end
+
+ sub_test_case("==") do
+ def test_true
+ assert_equal(Arrow::LiteralExpression.new(@datum),
+ Arrow::LiteralExpression.new(@datum))
+ end
+
+ def test_false
+ assert_not_equal(@expression,
+ Arrow::FieldExpression.new("visible"))
+ end
+ end
+
+ def test_to_string
+ assert_equal("true", @expression.to_s)
+ end
+end
diff --git a/ruby/red-arrow/lib/arrow/expression.rb
b/ruby/red-arrow/lib/arrow/expression.rb
new file mode 100644
index 0000000..a33cc53
--- /dev/null
+++ b/ruby/red-arrow/lib/arrow/expression.rb
@@ -0,0 +1,48 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+module Arrow
+ class Expression
+ class << self
+ # @api private
+ def try_convert(value)
+ case value
+ when Symbol
+ FieldExpression.new(value.to_s)
+ when ::Array
+ function_name, *arguments = value
+ case function_name
+ when String, Symbol
+ function_name = function_name.to_s
+ else
+ return nil
+ end
+ if arguments.last.is_a?(FunctionOptions)
+ options = arguments.pop
+ else
+ options = nil
+ end
+ CallExpression.new(function_name, arguments, options)
+ else
+ datum = Datum.try_convert(value)
+ return nil if datum.nil?
+ LiteralExpression.new(datum)
+ end
+ end
+ end
+ end
+end
diff --git a/ruby/red-arrow/lib/arrow/loader.rb
b/ruby/red-arrow/lib/arrow/loader.rb
index 267f1f3..804a948 100644
--- a/ruby/red-arrow/lib/arrow/loader.rb
+++ b/ruby/red-arrow/lib/arrow/loader.rb
@@ -70,6 +70,7 @@ module Arrow
require "arrow/dictionary-array"
require "arrow/dictionary-data-type"
require "arrow/equal-options"
+ require "arrow/expression"
require "arrow/field"
require "arrow/file-output-stream"
require "arrow/file-system"
diff --git a/ruby/red-arrow/test/test-expression.rb
b/ruby/red-arrow/test/test-expression.rb
new file mode 100644
index 0000000..e172e78
--- /dev/null
+++ b/ruby/red-arrow/test/test-expression.rb
@@ -0,0 +1,40 @@
+# 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 TestExpression < Test::Unit::TestCase
+ sub_test_case(".try_convert") do
+ test("Symbol") do
+ assert_equal(Arrow::FieldExpression.new("visible"),
+ Arrow::Expression.try_convert(:visible))
+ end
+
+ test("[String]") do
+ assert_equal(Arrow::CallExpression.new("func", []),
+ Arrow::Expression.try_convert(["func"]))
+ end
+
+ test("[Symbol]") do
+ assert_equal(Arrow::CallExpression.new("func", []),
+ Arrow::Expression.try_convert([:func]))
+ end
+
+ test("[String, String]") do
+ assert_equal(Arrow::CallExpression.new("func", ["argument1"]),
+ Arrow::Expression.try_convert(["func", "argument1"]))
+ end
+ end
+end