diff --git a/c_glib/arrow-glib/compute-definition.h b/c_glib/arrow-glib/compute-definition.h index ba0e9da9893f7..e27bc4bd5c5be 100644 --- a/c_glib/arrow-glib/compute-definition.h +++ b/c_glib/arrow-glib/compute-definition.h @@ -46,5 +46,16 @@ struct _GArrowCastOptionsClass GArrowFunctionOptionsClass parent_class; }; +#define GARROW_TYPE_EXPRESSION (garrow_expression_get_type()) +G_DECLARE_DERIVABLE_TYPE(GArrowExpression, + garrow_expression, + GARROW, + EXPRESSION, + GObject) +struct _GArrowExpressionClass +{ + GObjectClass parent_class; +}; + G_END_DECLS diff --git a/c_glib/arrow-glib/compute.cpp b/c_glib/arrow-glib/compute.cpp index 9338bf8515cc5..987de8d39cb76 100644 --- a/c_glib/arrow-glib/compute.cpp +++ b/c_glib/arrow-glib/compute.cpp @@ -178,6 +178,8 @@ G_BEGIN_DECLS * * #GArrowSourceNodeOptions is a class to customize a source node. * + * #GArrowFilterNodeOptions is a class to customize a filter node. + * * #GArrowProjectNodeOptions is a class to customize a project node. * * #GArrowAggregation is a class to specify how to aggregate. @@ -1059,6 +1061,41 @@ garrow_source_node_options_new_table(GArrowTable *table) } +G_DEFINE_TYPE(GArrowFilterNodeOptions, + garrow_filter_node_options, + GARROW_TYPE_EXECUTE_NODE_OPTIONS) + +static void +garrow_filter_node_options_init(GArrowFilterNodeOptions *object) +{ +} + +static void +garrow_filter_node_options_class_init(GArrowFilterNodeOptionsClass *klass) +{ +} + +/** + * garrow_filter_node_options_new: + * @expression: A #GArrowExpression to be used for filter. + * + * Returns: A newly created #GArrowFilterNodeOptions. + * + * Since: 12.0.0 + */ +GArrowFilterNodeOptions * +garrow_filter_node_options_new(GArrowExpression *expression) +{ + auto arrow_expression = garrow_expression_get_raw(expression); + auto arrow_options = + new arrow::compute::FilterNodeOptions(*arrow_expression); + auto options = g_object_new(GARROW_TYPE_FILTER_NODE_OPTIONS, + "options", arrow_options, + NULL); + return GARROW_FILTER_NODE_OPTIONS(options); +} + + G_DEFINE_TYPE(GArrowProjectNodeOptions, garrow_project_node_options, GARROW_TYPE_EXECUTE_NODE_OPTIONS) @@ -1871,6 +1908,39 @@ garrow_execute_plan_build_source_node(GArrowExecutePlan *plan, error); } +/** + * garrow_execute_plan_build_filter_node: + * @plan: A #GArrowExecutePlan. + * @input: A #GArrowExecuteNode. + * @options: A #GArrowFilterNodeOptions. + * @error: (nullable): Return location for a #GError or %NULL. + * + * This is a shortcut of garrow_execute_plan_build_node() for filter + * node. + * + * Returns: (transfer full): A newly built and added #GArrowExecuteNode + * for filter on success, %NULL on error. + * + * Since: 12.0.0 + */ +GArrowExecuteNode * +garrow_execute_plan_build_filter_node(GArrowExecutePlan *plan, + GArrowExecuteNode *input, + GArrowFilterNodeOptions *options, + GError **error) +{ + GList *inputs = nullptr; + inputs = g_list_prepend(inputs, input); + auto node = + garrow_execute_plan_build_node(plan, + "filter", + inputs, + GARROW_EXECUTE_NODE_OPTIONS(options), + error); + g_list_free(inputs); + return node; +} + /** * garrow_execute_plan_build_project_node: * @plan: A #GArrowExecutePlan. diff --git a/c_glib/arrow-glib/compute.h b/c_glib/arrow-glib/compute.h index cabb4a1482a60..673018137db12 100644 --- a/c_glib/arrow-glib/compute.h +++ b/c_glib/arrow-glib/compute.h @@ -156,6 +156,22 @@ GArrowSourceNodeOptions * garrow_source_node_options_new_table(GArrowTable *table); +#define GARROW_TYPE_FILTER_NODE_OPTIONS (garrow_filter_node_options_get_type()) +G_DECLARE_DERIVABLE_TYPE(GArrowFilterNodeOptions, + garrow_filter_node_options, + GARROW, + FILTER_NODE_OPTIONS, + GArrowExecuteNodeOptions) +struct _GArrowFilterNodeOptionsClass +{ + GArrowExecuteNodeOptionsClass parent_class; +}; + +GARROW_AVAILABLE_IN_12_0 +GArrowFilterNodeOptions * +garrow_filter_node_options_new(GArrowExpression *expression); + + #define GARROW_TYPE_PROJECT_NODE_OPTIONS (garrow_project_node_options_get_type()) G_DECLARE_DERIVABLE_TYPE(GArrowProjectNodeOptions, garrow_project_node_options, @@ -339,6 +355,12 @@ GArrowExecuteNode * garrow_execute_plan_build_source_node(GArrowExecutePlan *plan, GArrowSourceNodeOptions *options, GError **error); +GARROW_AVAILABLE_IN_12_0 +GArrowExecuteNode * +garrow_execute_plan_build_filter_node(GArrowExecutePlan *plan, + GArrowExecuteNode *input, + GArrowFilterNodeOptions *options, + GError **error); GARROW_AVAILABLE_IN_11_0 GArrowExecuteNode * garrow_execute_plan_build_project_node(GArrowExecutePlan *plan, diff --git a/c_glib/arrow-glib/expression.h b/c_glib/arrow-glib/expression.h index 1c1a5fbabcf2d..a161b8306be5c 100644 --- a/c_glib/arrow-glib/expression.h +++ b/c_glib/arrow-glib/expression.h @@ -23,17 +23,6 @@ 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); diff --git a/c_glib/test/test-filter-node.rb b/c_glib/test/test-filter-node.rb new file mode 100644 index 0000000000000..76624da9879f1 --- /dev/null +++ b/c_glib/test/test-filter-node.rb @@ -0,0 +1,55 @@ +# 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 TestFilterNode < Test::Unit::TestCase + include Helper::Buildable + + def execute_plan(options) + plan = Arrow::ExecutePlan.new + numbers = build_int8_array([1, 2, 3, 4, 5]) + table = build_table(number: numbers) + source_node_options = Arrow::SourceNodeOptions.new(table) + source_node = plan.build_source_node(source_node_options) + filter_node = plan.build_filter_node(source_node, options) + sink_node_options = Arrow::SinkNodeOptions.new + sink_node = plan.build_sink_node(filter_node, + sink_node_options) + plan.validate + plan.start + plan.wait + reader = sink_node_options.get_reader(filter_node.output_schema) + table = reader.read_all + plan.stop + table + end + + def test_expression + three_scalar = Arrow::Int8Scalar.new(3) + three_datum = Arrow::ScalarDatum.new(three_scalar) + expression = + Arrow::CallExpression.new("greater", + [ + Arrow::FieldExpression.new("number"), + Arrow::LiteralExpression.new(three_datum), + ]) + options = Arrow::FilterNodeOptions.new(expression) + assert_equal(build_table("number" => [ + build_int8_array([4, 5]), + ]), + execute_plan(options)) + end +end