From bdd04c0d470e193a8e4cb0fc1aa71eaa4cfb1197 Mon Sep 17 00:00:00 2001 From: Sten Larsson Date: Fri, 8 Mar 2024 06:26:41 +0100 Subject: [PATCH] GH-40402: [GLib] Add missing compute function options classes (#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: #40402 Lead-authored-by: Sten Larsson Co-authored-by: Sutou Kouhei Signed-off-by: Sutou Kouhei --- c_glib/arrow-glib/compute.cpp | 622 ++++++++++++++++++++++ c_glib/arrow-glib/compute.h | 69 +++ c_glib/arrow-glib/compute.hpp | 24 + c_glib/test/test-function.rb | 30 ++ c_glib/test/test-split-pattern-options.rb | 56 ++ c_glib/test/test-strftime-options.rb | 47 ++ c_glib/test/test-strptime-options.rb | 57 ++ c_glib/test/test-struct-field-options.rb | 75 +++ 8 files changed, 980 insertions(+) create mode 100644 c_glib/test/test-split-pattern-options.rb create mode 100644 c_glib/test/test-strftime-options.rb create mode 100644 c_glib/test/test-strptime-options.rb create mode 100644 c_glib/test/test-struct-field-options.rb diff --git a/c_glib/arrow-glib/compute.cpp b/c_glib/arrow-glib/compute.cpp index 9692f277d183f..14be097221dea 100644 --- a/c_glib/arrow-glib/compute.cpp +++ b/c_glib/arrow-glib/compute.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -240,6 +241,16 @@ G_BEGIN_DECLS * #GArrowRunEndEncodeOptions is a class to customize the * `run_end_encode` function. * + * #GArrowStrptimeOptions is a class to customize the `strptime` function. + * + * #GArrowStrftimeOptions is a class to customize the `strftime` function. + * + * #GArrowSplitPatternOptions is a class to customize the `split_pattern` and + * `split_pattern_regex` functions. + * + * #GArrowStructFieldOptions is a class to customize the `struct_field` + * function. + * * There are many functions to compute data on an array. */ @@ -6073,6 +6084,523 @@ garrow_run_end_encoded_array_decode(GArrowRunEndEncodedArray *array, } } +enum { + PROP_STRPTIME_OPTIONS_FORMAT = 1, + PROP_STRPTIME_OPTIONS_UNIT, + PROP_STRPTIME_OPTIONS_ERROR_IS_NULL, +}; + +G_DEFINE_TYPE(GArrowStrptimeOptions, + garrow_strptime_options, + GARROW_TYPE_FUNCTION_OPTIONS) + +static void +garrow_strptime_options_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + auto options = + garrow_strptime_options_get_raw(GARROW_STRPTIME_OPTIONS(object)); + + switch (prop_id) { + case PROP_STRPTIME_OPTIONS_FORMAT: + options->format = g_value_get_string(value); + break; + case PROP_STRPTIME_OPTIONS_UNIT: + options->unit = garrow_time_unit_to_raw( + static_cast(g_value_get_enum(value))); + break; + case PROP_STRPTIME_OPTIONS_ERROR_IS_NULL: + options->error_is_null = g_value_get_boolean(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +garrow_strptime_options_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + auto options = + garrow_strptime_options_get_raw(GARROW_STRPTIME_OPTIONS(object)); + + switch (prop_id) { + case PROP_STRPTIME_OPTIONS_FORMAT: + g_value_set_string(value, options->format.c_str()); + break; + case PROP_STRPTIME_OPTIONS_UNIT: + g_value_set_enum(value, garrow_time_unit_from_raw(options->unit)); + break; + case PROP_STRPTIME_OPTIONS_ERROR_IS_NULL: + g_value_set_boolean(value, options->error_is_null); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +garrow_strptime_options_init(GArrowStrptimeOptions *object) +{ + auto priv = GARROW_FUNCTION_OPTIONS_GET_PRIVATE(object); + priv->options = static_cast( + new arrow::compute::StrptimeOptions()); +} + +static void +garrow_strptime_options_class_init(GArrowStrptimeOptionsClass *klass) +{ + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->set_property = garrow_strptime_options_set_property; + gobject_class->get_property = garrow_strptime_options_get_property; + + arrow::compute::StrptimeOptions options; + + GParamSpec *spec; + /** + * GArrowStrptimeOptions:format: + * + * The desired format string. + * + * Since: 16.0.0 + */ + spec = g_param_spec_string("format", + "Format", + "The desired format string", + options.format.c_str(), + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, + PROP_STRPTIME_OPTIONS_FORMAT, + spec); + + /** + * GArrowStrptimeOptions:unit: + * + * The desired time resolution. + * + * Since: 16.0.0 + */ + spec = g_param_spec_enum("unit", + "Unit", + "The desired time resolution", + GARROW_TYPE_TIME_UNIT, + garrow_time_unit_from_raw(options.unit), + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, + PROP_STRPTIME_OPTIONS_UNIT, + spec); + + /** + * GArrowStrptimeOptions:error-is-null: + * + * Return null on parsing errors if true or raise if false. + * + * Since: 16.0.0 + */ + spec = g_param_spec_boolean("error-is-null", + "Error is null", + "Return null on parsing errors if true or raise if false", + options.error_is_null, + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, + PROP_STRPTIME_OPTIONS_ERROR_IS_NULL, + spec); +} + +/** + * garrow_strptime_options_new: + * + * Returns: A newly created #GArrowStrptimeOptions. + * + * Since: 16.0.0 + */ +GArrowStrptimeOptions * +garrow_strptime_options_new(void) +{ + auto options = g_object_new(GARROW_TYPE_STRPTIME_OPTIONS, NULL); + return GARROW_STRPTIME_OPTIONS(options); +} + +enum { + PROP_STRFTIME_OPTIONS_FORMAT = 1, + PROP_STRFTIME_OPTIONS_LOCALE, +}; + +G_DEFINE_TYPE(GArrowStrftimeOptions, + garrow_strftime_options, + GARROW_TYPE_FUNCTION_OPTIONS) + +static void +garrow_strftime_options_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + auto options = + garrow_strftime_options_get_raw(GARROW_STRFTIME_OPTIONS(object)); + + switch (prop_id) { + case PROP_STRFTIME_OPTIONS_FORMAT: + options->format = g_value_get_string(value); + break; + case PROP_STRFTIME_OPTIONS_LOCALE: + options->locale = g_value_get_string(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +garrow_strftime_options_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + auto options = + garrow_strftime_options_get_raw(GARROW_STRFTIME_OPTIONS(object)); + + switch (prop_id) { + case PROP_STRFTIME_OPTIONS_FORMAT: + g_value_set_string(value, options->format.c_str()); + break; + case PROP_STRFTIME_OPTIONS_LOCALE: + g_value_set_string(value, options->locale.c_str()); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +garrow_strftime_options_init(GArrowStrftimeOptions *object) +{ + auto priv = GARROW_FUNCTION_OPTIONS_GET_PRIVATE(object); + priv->options = static_cast( + new arrow::compute::StrftimeOptions()); +} + +static void +garrow_strftime_options_class_init(GArrowStrftimeOptionsClass *klass) +{ + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->set_property = garrow_strftime_options_set_property; + gobject_class->get_property = garrow_strftime_options_get_property; + + arrow::compute::StrftimeOptions options; + + GParamSpec *spec; + /** + * GArrowStrftimeOptions:format: + * + * The desired format string. + * + * Since: 16.0.0 + */ + spec = g_param_spec_string("format", + "Format", + "The desired format string", + options.format.c_str(), + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, + PROP_STRFTIME_OPTIONS_FORMAT, + spec); + + /** + * GArrowStrftimeOptions:locale: + * + * The desired output locale string. + * + * Since: 16.0.0 + */ + spec = g_param_spec_string("locale", + "locale", + "The desired output locale string", + options.locale.c_str(), + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, + PROP_STRFTIME_OPTIONS_LOCALE, + spec); +} + +/** + * garrow_strftime_options_new: + * + * Returns: A newly created #GArrowStrftimeOptions. + * + * Since: 16.0.0 + */ +GArrowStrftimeOptions * +garrow_strftime_options_new(void) +{ + auto options = g_object_new(GARROW_TYPE_STRFTIME_OPTIONS, NULL); + return GARROW_STRFTIME_OPTIONS(options); +} + +enum { + PROP_SPLIT_PATTERN_OPTIONS_PATTERN = 1, + PROP_SPLIT_PATTERN_OPTIONS_MAX_SPLITS, + PROP_SPLIT_PATTERN_OPTIONS_REVERSE, +}; + +G_DEFINE_TYPE(GArrowSplitPatternOptions, + garrow_split_pattern_options, + GARROW_TYPE_FUNCTION_OPTIONS) + +static void +garrow_split_pattern_options_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + auto options = garrow_split_pattern_options_get_raw( + GARROW_SPLIT_PATTERN_OPTIONS(object)); + + switch (prop_id) { + case PROP_SPLIT_PATTERN_OPTIONS_PATTERN: + options->pattern = g_value_get_string(value); + break; + case PROP_SPLIT_PATTERN_OPTIONS_MAX_SPLITS: + options->max_splits = g_value_get_int64(value); + break; + case PROP_SPLIT_PATTERN_OPTIONS_REVERSE: + options->reverse = g_value_get_boolean(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +garrow_split_pattern_options_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + auto options = garrow_split_pattern_options_get_raw( + GARROW_SPLIT_PATTERN_OPTIONS(object)); + + switch (prop_id) { + case PROP_SPLIT_PATTERN_OPTIONS_PATTERN: + g_value_set_string(value, options->pattern.c_str()); + break; + case PROP_SPLIT_PATTERN_OPTIONS_MAX_SPLITS: + g_value_set_int64(value, options->max_splits); + break; + case PROP_SPLIT_PATTERN_OPTIONS_REVERSE: + g_value_set_boolean(value, options->reverse); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +garrow_split_pattern_options_init(GArrowSplitPatternOptions *object) +{ + auto priv = GARROW_FUNCTION_OPTIONS_GET_PRIVATE(object); + priv->options = static_cast( + new arrow::compute::SplitPatternOptions()); +} + +static void +garrow_split_pattern_options_class_init(GArrowSplitPatternOptionsClass *klass) +{ + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->set_property = garrow_split_pattern_options_set_property; + gobject_class->get_property = garrow_split_pattern_options_get_property; + + arrow::compute::SplitPatternOptions options; + + GParamSpec *spec; + /** + * GArrowSplitPatternOptions:pattern: + * + * The exact substring to split on. + * + * Since: 16.0.0 + */ + spec = g_param_spec_string("pattern", + "Pattern", + "The exact substring to split on", + options.pattern.c_str(), + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, + PROP_SPLIT_PATTERN_OPTIONS_PATTERN, + spec); + + /** + * GArrowSplitPatternOptions:max_splits: + * + * Maximum number of splits allowed, or unlimited when -1. + * + * Since: 16.0.0 + */ + spec = g_param_spec_int64("max_splits", + "Max splits", + "Maximum number of splits allowed, or unlimited when -1", + G_MININT64, + G_MAXINT64, + options.max_splits, + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, + PROP_SPLIT_PATTERN_OPTIONS_MAX_SPLITS, + spec); + + /** + * GArrowSplitPatternOptions:reverse: + * + * Start splitting from the end of the string (only relevant when + * max_splits != -1) + * + * Since: 16.0.0 + */ + spec = g_param_spec_boolean("reverse", + "Reverse", + "Start splitting from the end of the string (only relevant when max_splits != -1)", + options.reverse, + static_cast(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, + PROP_SPLIT_PATTERN_OPTIONS_REVERSE, + spec); +} + +/** + * garrow_split_pattern_options_new: + * + * Returns: A newly created #GArrowSplitPatternOptions. + * + * Since: 16.0.0 + */ +GArrowSplitPatternOptions * +garrow_split_pattern_options_new(void) +{ + auto options = g_object_new(GARROW_TYPE_SPLIT_PATTERN_OPTIONS, NULL); + return GARROW_SPLIT_PATTERN_OPTIONS(options); +} + +enum { + PROP_STRUCT_FIELD_OPTIONS_FIELD_REF = 1, +}; + +G_DEFINE_TYPE(GArrowStructFieldOptions, + garrow_struct_field_options, + GARROW_TYPE_FUNCTION_OPTIONS) + +/** + * garrow_struct_field_options_set_field_ref: + * @field_ref: The name or dot path specifying what to extract from struct or + * union. + * + * Since: 16.0.0 + */ +void +garrow_struct_field_options_set_field_ref(GArrowStructFieldOptions *options, + const gchar *field_ref, + GError **error) +{ + auto arrow_options = garrow_struct_field_options_get_raw( + GARROW_STRUCT_FIELD_OPTIONS(options)); + + auto arrow_reference_result = garrow_field_reference_resolve_raw(field_ref); + if (!garrow::check(error, + arrow_reference_result, + "[struct-field-options][set-field-ref]")) { + return; + } + arrow_options->field_ref = *arrow_reference_result; +} + +static void +garrow_struct_field_options_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + auto options = garrow_struct_field_options_get_raw( + GARROW_STRUCT_FIELD_OPTIONS(object)); + + switch (prop_id) { + case PROP_STRUCT_FIELD_OPTIONS_FIELD_REF: + { + auto name = options->field_ref.name(); + if (name) { + g_value_set_string(value, name->c_str()); + } else { + g_value_set_string(value, options->field_ref.ToDotPath().c_str()); + } + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +garrow_struct_field_options_init(GArrowStructFieldOptions *object) +{ + auto priv = GARROW_FUNCTION_OPTIONS_GET_PRIVATE(object); + priv->options = static_cast( + new arrow::compute::StructFieldOptions()); +} + +static void +garrow_struct_field_options_class_init(GArrowStructFieldOptionsClass *klass) +{ + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->get_property = garrow_struct_field_options_get_property; + + GParamSpec *spec; + /** + * GArrowStructFieldOptions:field_ref: + * + * The name or dot path specifying what to extract from struct or union. + * + * dot_path = '.' name + * | '[' digit+ ']' + * | dot_path+ + * + * Since: 16.0.0 + */ + spec = g_param_spec_string("field_ref", + "Field ref", + "The name or dot path specifying what to extract from struct or union.", + "", + static_cast(G_PARAM_READABLE)); + g_object_class_install_property(gobject_class, + PROP_STRUCT_FIELD_OPTIONS_FIELD_REF, + spec); +} + +/** + * garrow_struct_field_options_new: + * + * Returns: A newly created #GArrowStructFieldOptions. + * + * Since: 16.0.0 + */ +GArrowStructFieldOptions * +garrow_struct_field_options_new(void) +{ + auto options = g_object_new(GARROW_TYPE_STRUCT_FIELD_OPTIONS, NULL); + return GARROW_STRUCT_FIELD_OPTIONS(options); +} + G_END_DECLS @@ -6191,6 +6719,26 @@ garrow_function_options_new_raw( auto options = garrow_run_end_encode_options_new_raw(arrow_run_end_encode_options); return GARROW_FUNCTION_OPTIONS(options); + } else if (arrow_type_name == "StrptimeOptions") { + const auto arrow_strptime_options = + static_cast(arrow_options); + auto options = garrow_strptime_options_new_raw(arrow_strptime_options); + return GARROW_FUNCTION_OPTIONS(options); + } else if (arrow_type_name == "StrftimeOptions") { + const auto arrow_strftime_options = + static_cast(arrow_options); + auto options = garrow_strftime_options_new_raw(arrow_strftime_options); + return GARROW_FUNCTION_OPTIONS(options); + } else if (arrow_type_name == "SplitPatternOptions") { + const auto arrow_split_pattern_options = + static_cast(arrow_options); + auto options = garrow_split_pattern_options_new_raw(arrow_split_pattern_options); + return GARROW_FUNCTION_OPTIONS(options); + } else if (arrow_type_name == "StructFieldOptions") { + const auto arrow_struct_field_options = + static_cast(arrow_options); + auto options = garrow_struct_field_options_new_raw(arrow_struct_field_options); + return GARROW_FUNCTION_OPTIONS(options); } else { auto options = g_object_new(GARROW_TYPE_FUNCTION_OPTIONS, NULL); @@ -6667,3 +7215,77 @@ garrow_run_end_encode_options_get_raw(GArrowRunEndEncodeOptions *options) return static_cast( garrow_function_options_get_raw(GARROW_FUNCTION_OPTIONS(options))); } + +GArrowStrptimeOptions * +garrow_strptime_options_new_raw( + const arrow::compute::StrptimeOptions *arrow_options) +{ + return GARROW_STRPTIME_OPTIONS( + g_object_new(GARROW_TYPE_STRPTIME_OPTIONS, + "format", arrow_options->format.c_str(), + "unit", arrow_options->unit, + "error_is_null", arrow_options->error_is_null, + NULL)); +} + +arrow::compute::StrptimeOptions * +garrow_strptime_options_get_raw(GArrowStrptimeOptions *options) +{ + return static_cast( + garrow_function_options_get_raw(GARROW_FUNCTION_OPTIONS(options))); +} + +GArrowStrftimeOptions * +garrow_strftime_options_new_raw( + const arrow::compute::StrftimeOptions *arrow_options) +{ + return GARROW_STRFTIME_OPTIONS( + g_object_new(GARROW_TYPE_STRFTIME_OPTIONS, + "format", arrow_options->format.c_str(), + "locale", arrow_options->locale.c_str(), + NULL)); +} + +arrow::compute::StrftimeOptions * +garrow_strftime_options_get_raw(GArrowStrftimeOptions *options) +{ + return static_cast( + garrow_function_options_get_raw(GARROW_FUNCTION_OPTIONS(options))); +} + +GArrowSplitPatternOptions * +garrow_split_pattern_options_new_raw( + const arrow::compute::SplitPatternOptions *arrow_options) +{ + return GARROW_SPLIT_PATTERN_OPTIONS( + g_object_new(GARROW_TYPE_SPLIT_PATTERN_OPTIONS, + "pattern", arrow_options->pattern.c_str(), + "max_splits", arrow_options->max_splits, + "reverse", arrow_options->reverse, + NULL)); +} + +arrow::compute::SplitPatternOptions * +garrow_split_pattern_options_get_raw(GArrowSplitPatternOptions *options) +{ + return static_cast( + garrow_function_options_get_raw(GARROW_FUNCTION_OPTIONS(options))); +} + +GArrowStructFieldOptions * +garrow_struct_field_options_new_raw( + const arrow::compute::StructFieldOptions *arrow_options) +{ + auto options = GARROW_STRUCT_FIELD_OPTIONS( + g_object_new(GARROW_TYPE_STRUCT_FIELD_OPTIONS, NULL)); + auto arrow_new_options = garrow_struct_field_options_get_raw(options); + arrow_new_options->field_ref = arrow_options->field_ref; + return options; +} + +arrow::compute::StructFieldOptions * +garrow_struct_field_options_get_raw(GArrowStructFieldOptions *options) +{ + return static_cast( + garrow_function_options_get_raw(GARROW_FUNCTION_OPTIONS(options))); +} diff --git a/c_glib/arrow-glib/compute.h b/c_glib/arrow-glib/compute.h index 008ae2a783860..9509e6d977aca 100644 --- a/c_glib/arrow-glib/compute.h +++ b/c_glib/arrow-glib/compute.h @@ -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 diff --git a/c_glib/arrow-glib/compute.hpp b/c_glib/arrow-glib/compute.hpp index 50074d0c98eba..4179a9ee733fd 100644 --- a/c_glib/arrow-glib/compute.hpp +++ b/c_glib/arrow-glib/compute.hpp @@ -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); diff --git a/c_glib/test/test-function.rb b/c_glib/test/test-function.rb index cffaacba03192..43d491978532b 100644 --- a/c_glib/test/test-function.rb +++ b/c_glib/test/test-function.rb @@ -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 @@ -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 diff --git a/c_glib/test/test-split-pattern-options.rb b/c_glib/test/test-split-pattern-options.rb new file mode 100644 index 0000000000000..b6bb5fe01f980 --- /dev/null +++ b/c_glib/test/test-split-pattern-options.rb @@ -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 diff --git a/c_glib/test/test-strftime-options.rb b/c_glib/test/test-strftime-options.rb new file mode 100644 index 0000000000000..81440d5d086ad --- /dev/null +++ b/c_glib/test/test-strftime-options.rb @@ -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 diff --git a/c_glib/test/test-strptime-options.rb b/c_glib/test/test-strptime-options.rb new file mode 100644 index 0000000000000..994176638a1ee --- /dev/null +++ b/c_glib/test/test-strptime-options.rb @@ -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 diff --git a/c_glib/test/test-struct-field-options.rb b/c_glib/test/test-struct-field-options.rb new file mode 100644 index 0000000000000..4a614de6df6e7 --- /dev/null +++ b/c_glib/test/test-struct-field-options.rb @@ -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