Skip to content

Commit

Permalink
apacheGH-40402: [GLib] Add missing compute function options classes (a…
Browse files Browse the repository at this point in the history
…pache#40403)

### Rationale for this change

In most cases the options to compute functions are optional, but there are cases where they are required. The following compute functions are not possible to use in Ruby because the required options classes are missing from the GLib bindings:

* `split_pattern`
* `strftime` (can technically be used)
* `strptime`
* `struct_field`

There are probably more functions that cannot be used, but this is a start.

### What changes are included in this PR?

The following GLib classes are added:

* `GArrowSplitPatternOptions`
* `GArrowStrftimeOptions`
* `GArrowStrptimeOptions`
* `GArrowStructFieldOptions`

To be able to return an error, a separate function for setting the field_ref on StructFieldOptions is used instead of a set_property function.

### Are these changes tested?

Yes

### Are there any user-facing changes?

Yes

* GitHub Issue: apache#40402

Lead-authored-by: Sten Larsson <[email protected]>
Co-authored-by: Sutou Kouhei <[email protected]>
Signed-off-by: Sutou Kouhei <[email protected]>
  • Loading branch information
stenlarsson and kou authored Mar 8, 2024
1 parent 2a4df7a commit bdd04c0
Show file tree
Hide file tree
Showing 8 changed files with 980 additions and 0 deletions.
622 changes: 622 additions & 0 deletions c_glib/arrow-glib/compute.cpp

Large diffs are not rendered by default.

69 changes: 69 additions & 0 deletions c_glib/arrow-glib/compute.h
Original file line number Diff line number Diff line change
Expand Up @@ -1113,5 +1113,74 @@ GArrowArray *
garrow_run_end_encoded_array_decode(GArrowRunEndEncodedArray *array,
GError **error);

#define GARROW_TYPE_STRPTIME_OPTIONS \
(garrow_strptime_options_get_type())
G_DECLARE_DERIVABLE_TYPE(GArrowStrptimeOptions,
garrow_strptime_options,
GARROW,
STRPTIME_OPTIONS,
GArrowFunctionOptions)
struct _GArrowStrptimeOptionsClass
{
GArrowFunctionOptionsClass parent_class;
};

GARROW_AVAILABLE_IN_16_0
GArrowStrptimeOptions *
garrow_strptime_options_new(void);

#define GARROW_TYPE_STRFTIME_OPTIONS \
(garrow_strftime_options_get_type())
G_DECLARE_DERIVABLE_TYPE(GArrowStrftimeOptions,
garrow_strftime_options,
GARROW,
STRFTIME_OPTIONS,
GArrowFunctionOptions)
struct _GArrowStrftimeOptionsClass
{
GArrowFunctionOptionsClass parent_class;
};

GARROW_AVAILABLE_IN_16_0
GArrowStrftimeOptions *
garrow_strftime_options_new(void);

#define GARROW_TYPE_SPLIT_PATTERN_OPTIONS \
(garrow_split_pattern_options_get_type())
G_DECLARE_DERIVABLE_TYPE(GArrowSplitPatternOptions,
garrow_split_pattern_options,
GARROW,
SPLIT_PATTERN_OPTIONS,
GArrowFunctionOptions)
struct _GArrowSplitPatternOptionsClass
{
GArrowFunctionOptionsClass parent_class;
};

GARROW_AVAILABLE_IN_16_0
GArrowSplitPatternOptions *
garrow_split_pattern_options_new(void);

#define GARROW_TYPE_STRUCT_FIELD_OPTIONS \
(garrow_struct_field_options_get_type())
G_DECLARE_DERIVABLE_TYPE(GArrowStructFieldOptions,
garrow_struct_field_options,
GARROW,
STRUCT_FIELD_OPTIONS,
GArrowFunctionOptions)
struct _GArrowStructFieldOptionsClass
{
GArrowFunctionOptionsClass parent_class;
};

GARROW_AVAILABLE_IN_16_0
void
garrow_struct_field_options_set_field_ref(GArrowStructFieldOptions *options,
const gchar *field_ref,
GError **error);

GARROW_AVAILABLE_IN_16_0
GArrowStructFieldOptions *
garrow_struct_field_options_new(void);

G_END_DECLS
24 changes: 24 additions & 0 deletions c_glib/arrow-glib/compute.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,27 @@ garrow_run_end_encode_options_new_raw(
const arrow::compute::RunEndEncodeOptions *arrow_options);
arrow::compute::RunEndEncodeOptions *
garrow_run_end_encode_options_get_raw(GArrowRunEndEncodeOptions *options);

GArrowStrptimeOptions *
garrow_strptime_options_new_raw(
const arrow::compute::StrptimeOptions *arrow_options);
arrow::compute::StrptimeOptions *
garrow_strptime_options_get_raw(GArrowStrptimeOptions *options);

GArrowStrftimeOptions *
garrow_strftime_options_new_raw(
const arrow::compute::StrftimeOptions *arrow_options);
arrow::compute::StrftimeOptions *
garrow_strftime_options_get_raw(GArrowStrftimeOptions *options);

GArrowSplitPatternOptions *
garrow_split_pattern_options_new_raw(
const arrow::compute::SplitPatternOptions *arrow_options);
arrow::compute::SplitPatternOptions *
garrow_split_pattern_options_get_raw(GArrowSplitPatternOptions *options);

GArrowStructFieldOptions *
garrow_struct_field_options_new_raw(
const arrow::compute::StructFieldOptions *arrow_options);
arrow::compute::StructFieldOptions *
garrow_struct_field_options_get_raw(GArrowStructFieldOptions *options);
30 changes: 30 additions & 0 deletions c_glib/test/test-function.rb
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,12 @@ def test_round_to_multiple_options
assert_equal(Arrow::RoundToMultipleOptions.new,
round_to_multiple_function.default_options)
end

def test_strftime_options
strftime_function = Arrow::Function.find("strftime")
assert_equal(Arrow::StrftimeOptions.new,
strftime_function.default_options)
end
end

sub_test_case("#options_type") do
Expand Down Expand Up @@ -232,5 +238,29 @@ def test_round_to_multiple_options
assert_equal(Arrow::RoundToMultipleOptions.gtype,
round_to_multiple_function.options_type)
end

def test_strptime_options
strptime_function = Arrow::Function.find("strptime")
assert_equal(Arrow::StrptimeOptions.gtype,
strptime_function.options_type)
end

def test_strftime_options
strftime_function = Arrow::Function.find("strftime")
assert_equal(Arrow::StrftimeOptions.gtype,
strftime_function.options_type)
end

def test_split_pattern_options
split_pattern_function = Arrow::Function.find("split_pattern")
assert_equal(Arrow::SplitPatternOptions.gtype,
split_pattern_function.options_type)
end

def test_struct_field_options
struct_field_function = Arrow::Function.find("struct_field")
assert_equal(Arrow::StructFieldOptions.gtype,
struct_field_function.options_type)
end
end
end
56 changes: 56 additions & 0 deletions c_glib/test/test-split-pattern-options.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# 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 TestSplitPatternOptions < Test::Unit::TestCase
include Helper::Buildable

def setup
@options = Arrow::SplitPatternOptions.new
end

def test_pattern_property
assert_equal("", @options.pattern)
@options.pattern = "foo"
assert_equal("foo", @options.pattern)
end

def test_max_splits_property
assert_equal(-1, @options.max_splits)
@options.max_splits = 1
assert_equal(1, @options.max_splits)
end

def test_reverse_property
assert do
!@options.reverse?
end
@options.reverse = true
assert do
@options.reverse?
end
end

def test_split_pattern_regex_function
args = [
Arrow::ArrayDatum.new(build_string_array(["hello world"])),
]
@options.pattern = "[lo]+"
split_pattern_regex_function = Arrow::Function.find("split_pattern_regex")
assert_equal(build_list_array(Arrow::StringDataType.new, [["he", " w", "r", "d"]]),
split_pattern_regex_function.execute(args, @options).value)
end
end
47 changes: 47 additions & 0 deletions c_glib/test/test-strftime-options.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

class TestStrftimeOptions < Test::Unit::TestCase
include Helper::Buildable

def setup
@options = Arrow::StrftimeOptions.new
end

def test_format_property
assert_equal("%Y-%m-%dT%H:%M:%S", @options.format)
@options.format = "%Y-%m-%d"
assert_equal("%Y-%m-%d", @options.format)
end

def test_locale_property
assert_equal("C", @options.locale)
@options.locale = "sv_SE.UTF-8"
assert_equal("sv_SE.UTF-8", @options.locale)
end

def test_strftime_function
omit("Missing tzdata on Windows") if Gem.win_platform?
args = [
Arrow::ArrayDatum.new(build_timestamp_array(:milli, [1504953190854])),
]
@options.format = "%Y-%m-%d"
strftime_function = Arrow::Function.find("strftime")
assert_equal(build_string_array(["2017-09-09"]),
strftime_function.execute(args, @options).value)
end
end
57 changes: 57 additions & 0 deletions c_glib/test/test-strptime-options.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# 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 TestStrptimeOptions < Test::Unit::TestCase
include Helper::Buildable

def setup
@options = Arrow::StrptimeOptions.new
end

def test_format_property
assert_equal("", @options.format)
@options.format = "%Y-%m-%d"
assert_equal("%Y-%m-%d", @options.format)
end

def test_unit_property
assert_equal(Arrow::TimeUnit::MICRO, @options.unit)
@options.unit = :nano
assert_equal(Arrow::TimeUnit::NANO, @options.unit)
end

def test_error_is_null_property
assert do
!@options.error_is_null?
end
@options.error_is_null = true
assert do
@options.error_is_null?
end
end

def test_strptime_function
args = [
Arrow::ArrayDatum.new(build_string_array(["2017-09-09T10:33:10"])),
]
@options.format = "%Y-%m-%dT%H:%M:%S"
@options.unit = :milli
strptime_function = Arrow::Function.find("strptime")
assert_equal(build_timestamp_array(:milli, [1504953190000]),
strptime_function.execute(args, @options).value)
end
end
75 changes: 75 additions & 0 deletions c_glib/test/test-struct-field-options.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# 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 TestStructFieldOptions < Test::Unit::TestCase
include Helper::Buildable

def setup
@options = Arrow::StructFieldOptions.new
end

def test_default
assert_equal("", @options.field_ref)
end

def test_set_string
@options.field_ref = "foo"
assert_equal("foo", @options.field_ref)
end

def test_set_symbol
@options.field_ref = :foo
assert_equal("foo", @options.field_ref)
end

def test_set_dot_path
@options.field_ref = ".foo.bar"
assert_equal(".foo.bar", @options.field_ref)
end

def test_set_invalid
message = "[struct-field-options][set-field-ref]: Invalid: Dot path '[foo]' contained an unterminated index"
assert_raise(Arrow::Error::Invalid.new(message)) do
@options.field_ref = "[foo]"
end
end

def test_struct_field_function
fields = [
Arrow::Field.new("score", Arrow::Int8DataType.new),
Arrow::Field.new("enabled", Arrow::BooleanDataType.new),
]
structs = [
{
"score" => -29,
"enabled" => true,
},
{
"score" => 2,
"enabled" => false,
},
nil,
]
args = [
Arrow::ArrayDatum.new(build_struct_array(fields, structs)),
]
@options.field_ref = "score"
struct_field_function = Arrow::Function.find("struct_field")
assert_equal(build_int8_array([-29, 2, nil]),
struct_field_function.execute(args, @options).value)
end
end

0 comments on commit bdd04c0

Please sign in to comment.