diff --git a/c_glib/arrow-glib/basic-data-type.cpp b/c_glib/arrow-glib/basic-data-type.cpp index e7efcdcc124f..848256e1d167 100644 --- a/c_glib/arrow-glib/basic-data-type.cpp +++ b/c_glib/arrow-glib/basic-data-type.cpp @@ -27,6 +27,7 @@ #include #include +#include #include G_BEGIN_DECLS @@ -2591,6 +2592,212 @@ garrow_uuid_data_type_new(GError **error) return NULL; } } + +static arrow::extension::RangeClosed +garrow_range_closed_to_raw(GArrowRangeClosed closed) +{ + switch (closed) { + case GARROW_RANGE_CLOSED_LEFT: + return arrow::extension::RangeClosed::Left; + case GARROW_RANGE_CLOSED_RIGHT: + return arrow::extension::RangeClosed::Right; + case GARROW_RANGE_CLOSED_BOTH: + return arrow::extension::RangeClosed::Both; + case GARROW_RANGE_CLOSED_NEITHER: + return arrow::extension::RangeClosed::Neither; + default: + return arrow::extension::RangeClosed::Left; + } +} + +static GArrowRangeClosed +garrow_range_closed_from_raw(arrow::extension::RangeClosed closed) +{ + switch (closed) { + case arrow::extension::RangeClosed::Left: + return GARROW_RANGE_CLOSED_LEFT; + case arrow::extension::RangeClosed::Right: + return GARROW_RANGE_CLOSED_RIGHT; + case arrow::extension::RangeClosed::Both: + return GARROW_RANGE_CLOSED_BOTH; + case arrow::extension::RangeClosed::Neither: + return GARROW_RANGE_CLOSED_NEITHER; + default: + return GARROW_RANGE_CLOSED_LEFT; + } +} + +G_DEFINE_TYPE(GArrowFixedClosednessRangeDataType, + garrow_fixed_closedness_range_data_type, + GARROW_TYPE_EXTENSION_DATA_TYPE) + +static void +garrow_fixed_closedness_range_data_type_init(GArrowFixedClosednessRangeDataType *object) +{ +} + +static void +garrow_fixed_closedness_range_data_type_class_init( + GArrowFixedClosednessRangeDataTypeClass *klass) +{ +} + +/** + * garrow_fixed_closedness_range_data_type_new: + * @value_type: The orderable #GArrowDataType of the lower and upper bounds. + * @closed: Which bound(s) of the interval are inclusive. + * @allow_unbounded: Whether each side may be unbounded (infinite); when %TRUE + * the lower/upper fields are nullable, when %FALSE they are non-nullable and + * the range is always finite. + * @error: (nullable): Return location for a #GError or %NULL. + * + * Returns: (nullable): + * The newly created fixed closedness range data type on success, %NULL on + * error. + * + * Since: 26.0.0 + */ +GArrowFixedClosednessRangeDataType * +garrow_fixed_closedness_range_data_type_new(GArrowDataType *value_type, + GArrowRangeClosed closed, + gboolean allow_unbounded, + GError **error) +{ + auto arrow_value_type = garrow_data_type_get_raw(value_type); + auto arrow_closed = garrow_range_closed_to_raw(closed); + auto arrow_data_type_result = + arrow::extension::FixedClosednessRangeType::Make(arrow_value_type, + arrow_closed, + allow_unbounded); + if (garrow::check(error, + arrow_data_type_result, + "[fixed-closedness-range-data-type][new]")) { + auto arrow_data_type = *arrow_data_type_result; + return GARROW_FIXED_CLOSEDNESS_RANGE_DATA_TYPE( + g_object_new(GARROW_TYPE_FIXED_CLOSEDNESS_RANGE_DATA_TYPE, + "data-type", + &arrow_data_type, + NULL)); + } else { + return NULL; + } +} + +/** + * garrow_fixed_closedness_range_data_type_get_value_type: + * @data_type: A #GArrowFixedClosednessRangeDataType. + * + * Returns: (transfer full): The orderable #GArrowDataType of the lower + * and upper bounds. + * + * Since: 26.0.0 + */ +GArrowDataType * +garrow_fixed_closedness_range_data_type_get_value_type( + GArrowFixedClosednessRangeDataType *data_type) +{ + auto arrow_data_type = + std::static_pointer_cast( + garrow_data_type_get_raw(GARROW_DATA_TYPE(data_type))); + auto arrow_value_type = arrow_data_type->value_type(); + return garrow_data_type_new_raw(&arrow_value_type); +} + +/** + * garrow_fixed_closedness_range_data_type_get_closed: + * @data_type: A #GArrowFixedClosednessRangeDataType. + * + * Returns: Which bound(s) of the interval are inclusive. + * + * Since: 26.0.0 + */ +GArrowRangeClosed +garrow_fixed_closedness_range_data_type_get_closed( + GArrowFixedClosednessRangeDataType *data_type) +{ + auto arrow_data_type = + std::static_pointer_cast( + garrow_data_type_get_raw(GARROW_DATA_TYPE(data_type))); + return garrow_range_closed_from_raw(arrow_data_type->closed()); +} + +G_DEFINE_TYPE(GArrowVariableClosednessRangeDataType, + garrow_variable_closedness_range_data_type, + GARROW_TYPE_EXTENSION_DATA_TYPE) + +static void +garrow_variable_closedness_range_data_type_init( + GArrowVariableClosednessRangeDataType *object) +{ +} + +static void +garrow_variable_closedness_range_data_type_class_init( + GArrowVariableClosednessRangeDataTypeClass *klass) +{ +} + +/** + * garrow_variable_closedness_range_data_type_new: + * @value_type: The orderable #GArrowDataType of the lower and upper bounds. + * @allow_unbounded: Whether each side may be unbounded (infinite); when %TRUE + * the lower/upper fields are nullable, when %FALSE they are non-nullable and + * the range is always finite. The lower_inc/upper_inc fields are always + * non-nullable. + * @error: (nullable): Return location for a #GError or %NULL. + * + * Unlike #GArrowFixedClosednessRangeDataType, the inclusivity of each bound + * is stored per value in boolean lower_inc/upper_inc fields rather than as a + * single type-level parameter, so there is no closed argument. + * + * Returns: (nullable): + * The newly created variable closedness range data type on success, %NULL + * on error. + * + * Since: 26.0.0 + */ +GArrowVariableClosednessRangeDataType * +garrow_variable_closedness_range_data_type_new(GArrowDataType *value_type, + gboolean allow_unbounded, + GError **error) +{ + auto arrow_value_type = garrow_data_type_get_raw(value_type); + auto arrow_data_type_result = + arrow::extension::VariableClosednessRangeType::Make(arrow_value_type, + allow_unbounded); + if (garrow::check(error, + arrow_data_type_result, + "[variable-closedness-range-data-type][new]")) { + auto arrow_data_type = *arrow_data_type_result; + return GARROW_VARIABLE_CLOSEDNESS_RANGE_DATA_TYPE( + g_object_new(GARROW_TYPE_VARIABLE_CLOSEDNESS_RANGE_DATA_TYPE, + "data-type", + &arrow_data_type, + NULL)); + } else { + return NULL; + } +} + +/** + * garrow_variable_closedness_range_data_type_get_value_type: + * @data_type: A #GArrowVariableClosednessRangeDataType. + * + * Returns: (transfer full): The orderable #GArrowDataType of the lower + * and upper bounds. + * + * Since: 26.0.0 + */ +GArrowDataType * +garrow_variable_closedness_range_data_type_get_value_type( + GArrowVariableClosednessRangeDataType *data_type) +{ + auto arrow_data_type = + std::static_pointer_cast( + garrow_data_type_get_raw(GARROW_DATA_TYPE(data_type))); + auto arrow_value_type = arrow_data_type->value_type(); + return garrow_data_type_new_raw(&arrow_value_type); +} G_END_DECLS GArrowDataType * @@ -2746,6 +2953,10 @@ garrow_data_type_new_raw(std::shared_ptr *arrow_data_type) type = GARROW_TYPE_FIXED_SHAPE_TENSOR_DATA_TYPE; } else if (name == "arrow.uuid") { type = GARROW_TYPE_UUID_DATA_TYPE; + } else if (name == "arrow.fixed_closedness_range") { + type = GARROW_TYPE_FIXED_CLOSEDNESS_RANGE_DATA_TYPE; + } else if (name == "arrow.variable_closedness_range") { + type = GARROW_TYPE_VARIABLE_CLOSEDNESS_RANGE_DATA_TYPE; } else { auto g_extension_data_type = std::dynamic_pointer_cast(*arrow_data_type); diff --git a/c_glib/arrow-glib/basic-data-type.h b/c_glib/arrow-glib/basic-data-type.h index 21f4be7c0c60..36c5a20d9050 100644 --- a/c_glib/arrow-glib/basic-data-type.h +++ b/c_glib/arrow-glib/basic-data-type.h @@ -894,4 +894,79 @@ struct _GArrowUUIDDataTypeClass GARROW_AVAILABLE_IN_21_0 GArrowUUIDDataType * garrow_uuid_data_type_new(GError **error); + +/** + * GArrowRangeClosed: + * @GARROW_RANGE_CLOSED_LEFT: Lower bound is inclusive, upper bound is + * exclusive: [lower, upper). + * @GARROW_RANGE_CLOSED_RIGHT: Lower bound is exclusive, upper bound is + * inclusive: (lower, upper]. + * @GARROW_RANGE_CLOSED_BOTH: Both bounds are inclusive: [lower, upper]. + * @GARROW_RANGE_CLOSED_NEITHER: Both bounds are exclusive: (lower, upper). + * + * They are corresponding to `arrow::extension::RangeClosed` values. + * + * Since: 26.0.0 + */ +typedef enum { + GARROW_RANGE_CLOSED_LEFT, + GARROW_RANGE_CLOSED_RIGHT, + GARROW_RANGE_CLOSED_BOTH, + GARROW_RANGE_CLOSED_NEITHER, +} GArrowRangeClosed; + +#define GARROW_TYPE_FIXED_CLOSEDNESS_RANGE_DATA_TYPE \ + (garrow_fixed_closedness_range_data_type_get_type()) +GARROW_AVAILABLE_IN_26_0 +G_DECLARE_DERIVABLE_TYPE(GArrowFixedClosednessRangeDataType, + garrow_fixed_closedness_range_data_type, + GARROW, + FIXED_CLOSEDNESS_RANGE_DATA_TYPE, + GArrowExtensionDataType) +struct _GArrowFixedClosednessRangeDataTypeClass +{ + GArrowExtensionDataTypeClass parent_class; +}; + +GARROW_AVAILABLE_IN_26_0 +GArrowFixedClosednessRangeDataType * +garrow_fixed_closedness_range_data_type_new(GArrowDataType *value_type, + GArrowRangeClosed closed, + gboolean allow_unbounded, + GError **error); + +GARROW_AVAILABLE_IN_26_0 +GArrowDataType * +garrow_fixed_closedness_range_data_type_get_value_type( + GArrowFixedClosednessRangeDataType *data_type); + +GARROW_AVAILABLE_IN_26_0 +GArrowRangeClosed +garrow_fixed_closedness_range_data_type_get_closed( + GArrowFixedClosednessRangeDataType *data_type); + +#define GARROW_TYPE_VARIABLE_CLOSEDNESS_RANGE_DATA_TYPE \ + (garrow_variable_closedness_range_data_type_get_type()) +GARROW_AVAILABLE_IN_26_0 +G_DECLARE_DERIVABLE_TYPE(GArrowVariableClosednessRangeDataType, + garrow_variable_closedness_range_data_type, + GARROW, + VARIABLE_CLOSEDNESS_RANGE_DATA_TYPE, + GArrowExtensionDataType) +struct _GArrowVariableClosednessRangeDataTypeClass +{ + GArrowExtensionDataTypeClass parent_class; +}; + +GARROW_AVAILABLE_IN_26_0 +GArrowVariableClosednessRangeDataType * +garrow_variable_closedness_range_data_type_new(GArrowDataType *value_type, + gboolean allow_unbounded, + GError **error); + +GARROW_AVAILABLE_IN_26_0 +GArrowDataType * +garrow_variable_closedness_range_data_type_get_value_type( + GArrowVariableClosednessRangeDataType *data_type); + G_END_DECLS diff --git a/c_glib/test/test-fixed-closedness-range-data-type.rb b/c_glib/test/test-fixed-closedness-range-data-type.rb new file mode 100644 index 000000000000..a96b3a11edc5 --- /dev/null +++ b/c_glib/test/test-fixed-closedness-range-data-type.rb @@ -0,0 +1,90 @@ +# 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 TestFixedClosednessRangeDataType < Test::Unit::TestCase + def setup + @value_type = Arrow::Int32DataType.new + @data_type = Arrow::FixedClosednessRangeDataType.new(@value_type, + Arrow::RangeClosed::LEFT, + true) + end + + def test_id + assert_equal(Arrow::Type::EXTENSION, @data_type.id) + end + + def test_name + assert_equal(["extension", "arrow.fixed_closedness_range"], + [@data_type.name, @data_type.extension_name]) + end + + def test_value_type + assert_equal(@value_type, @data_type.value_type) + end + + def test_closed + assert_equal(Arrow::RangeClosed::LEFT, @data_type.closed) + end + + def test_to_s + assert do + @data_type.to_s.start_with?("extension