Skip to content

Commit

Permalink
GH-44392: [GLib] Add GArrowDecimal32DataType (#44580)
Browse files Browse the repository at this point in the history
### Rationale for this change

`arrow::Decimal32Type` data type has been introduced. It is also necessary to support the same data type in GLib.

### What changes are included in this PR?

This PR implements `GArrowDecimal32DataType`.

### Are these changes tested?

YES

### Are there any user-facing changes?

Before this change `garrow_decimal_data_type_new()` returns `GArrowDecimal64DataType` if the precision is less than `garrow_decimal64_data_type_max_precision()`.
After this change, it returns `GArrowDecimal32DataType` if the precision is less than garrow_decimal32_data_type_max_precision().

* GitHub Issue: #44392

Authored-by: Hiroyuki Sato <[email protected]>
Signed-off-by: Sutou Kouhei <[email protected]>
  • Loading branch information
hiroyuki-sato authored Oct 30, 2024
1 parent feafddd commit 5b68eca
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 6 deletions.
68 changes: 64 additions & 4 deletions c_glib/arrow-glib/basic-data-type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ G_BEGIN_DECLS
*
* #GArrowDecimalDataType is a base class for the decimal data types.
*
* #GArrowDecimal32DataType is a class for the 32-bit decimal data type.
*
* #GArrowDecimal64DataType is a class for the 64-bit decimal data type.
*
* #GArrowDecimal128DataType is a class for the 128-bit decimal data type.
Expand Down Expand Up @@ -1493,16 +1495,20 @@ garrow_decimal_data_type_class_init(GArrowDecimalDataTypeClass *klass)
* Returns: (nullable):
* The newly created decimal data type on success, %NULL on error.
*
* #GArrowDecimal256DataType is used if @precision is larger than
* garrow_decimal128_data_type_max_precision(),
* #GArrowDecimal128DataType is used otherwise.
* * #GArrowDecimal32DataType is used if @precision up to 9
* * #GArrowDecimal64DataType is used if @precision up to 19
* * #GArrowDecimal128DataType is used if @precision up to 38
* * #GArrowDecimal256DataType is used otherwise
*
* Since: 0.10.0
*/
GArrowDecimalDataType *
garrow_decimal_data_type_new(gint32 precision, gint32 scale, GError **error)
{
if (precision <= garrow_decimal64_data_type_max_precision()) {
if (precision <= garrow_decimal32_data_type_max_precision()) {
return GARROW_DECIMAL_DATA_TYPE(
garrow_decimal32_data_type_new(precision, scale, error));
} else if (precision <= garrow_decimal64_data_type_max_precision()) {
return GARROW_DECIMAL_DATA_TYPE(
garrow_decimal64_data_type_new(precision, scale, error));
} else if (precision <= garrow_decimal128_data_type_max_precision()) {
Expand Down Expand Up @@ -1550,6 +1556,57 @@ garrow_decimal_data_type_get_scale(GArrowDecimalDataType *decimal_data_type)
return arrow_decimal_type->scale();
}

G_DEFINE_TYPE(GArrowDecimal32DataType,
garrow_decimal32_data_type,
GARROW_TYPE_DECIMAL_DATA_TYPE)

static void
garrow_decimal32_data_type_init(GArrowDecimal32DataType *object)
{
}

static void
garrow_decimal32_data_type_class_init(GArrowDecimal32DataTypeClass *klass)
{
}

/**
* garrow_decimal32_data_type_max_precision:
*
* Returns: The max precision of 32-bit decimal data type.
*
* Since: 19.0.0
*/
gint32
garrow_decimal32_data_type_max_precision()
{
return arrow::Decimal32Type::kMaxPrecision;
}

/**
* garrow_decimal32_data_type_new:
* @precision: The precision of decimal data.
* @scale: The scale of decimal data.
* @error: (nullable): Return location for a #GError or %NULL.
*
* Returns: (nullable):
* The newly created 32-bit decimal data type on success, %NULL on error.
*
* Since: 19.0.0
*/
GArrowDecimal32DataType *
garrow_decimal32_data_type_new(gint32 precision, gint32 scale, GError **error)
{
auto arrow_data_type_result = arrow::Decimal32Type::Make(precision, scale);
if (garrow::check(error, arrow_data_type_result, "[decimal32-data-type][new]")) {
auto arrow_data_type = *arrow_data_type_result;
return GARROW_DECIMAL32_DATA_TYPE(
g_object_new(GARROW_TYPE_DECIMAL32_DATA_TYPE, "data-type", &arrow_data_type, NULL));
} else {
return NULL;
}
}

G_DEFINE_TYPE(GArrowDecimal64DataType,
garrow_decimal64_data_type,
GARROW_TYPE_DECIMAL_DATA_TYPE)
Expand Down Expand Up @@ -2249,6 +2306,9 @@ garrow_data_type_new_raw(std::shared_ptr<arrow::DataType> *arrow_data_type)
case arrow::Type::type::MAP:
type = GARROW_TYPE_MAP_DATA_TYPE;
break;
case arrow::Type::type::DECIMAL32:
type = GARROW_TYPE_DECIMAL32_DATA_TYPE;
break;
case arrow::Type::type::DECIMAL64:
type = GARROW_TYPE_DECIMAL64_DATA_TYPE;
break;
Expand Down
20 changes: 20 additions & 0 deletions c_glib/arrow-glib/basic-data-type.h
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,26 @@ GARROW_AVAILABLE_IN_ALL
gint32
garrow_decimal_data_type_get_scale(GArrowDecimalDataType *decimal_data_type);

#define GARROW_TYPE_DECIMAL32_DATA_TYPE (garrow_decimal32_data_type_get_type())
GARROW_AVAILABLE_IN_19_0
G_DECLARE_DERIVABLE_TYPE(GArrowDecimal32DataType,
garrow_decimal32_data_type,
GARROW,
DECIMAL32_DATA_TYPE,
GArrowDecimalDataType)
struct _GArrowDecimal32DataTypeClass
{
GArrowDecimalDataTypeClass parent_class;
};

GARROW_AVAILABLE_IN_19_0
gint32
garrow_decimal32_data_type_max_precision();

GARROW_AVAILABLE_IN_19_0
GArrowDecimal32DataType *
garrow_decimal32_data_type_new(gint32 precision, gint32 scale, GError **error);

#define GARROW_TYPE_DECIMAL64_DATA_TYPE (garrow_decimal64_data_type_get_type())
GARROW_AVAILABLE_IN_19_0
G_DECLARE_DERIVABLE_TYPE(GArrowDecimal64DataType,
Expand Down
2 changes: 2 additions & 0 deletions c_glib/arrow-glib/type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ garrow_type_from_raw(arrow::Type::type type)
return GARROW_TYPE_MONTH_INTERVAL;
case arrow::Type::type::INTERVAL_DAY_TIME:
return GARROW_TYPE_DAY_TIME_INTERVAL;
case arrow::Type::type::DECIMAL32:
return GARROW_TYPE_DECIMAL32;
case arrow::Type::type::DECIMAL64:
return GARROW_TYPE_DECIMAL64;
case arrow::Type::type::DECIMAL128:
Expand Down
6 changes: 4 additions & 2 deletions c_glib/arrow-glib/type.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ G_BEGIN_DECLS
* @GARROW_TYPE_LARGE_LIST: A list of some logical data type with 64-bit offsets.
* @GARROW_TYPE_MONTH_DAY_NANO_INTERVAL: MONTH_DAY_NANO interval in SQL style.
* @GARROW_TYPE_RUN_END_ENCODED: Run-end encoded data.
* @GARROW_TYPE_DECIMAL32: Precision- and scale-based decimal
* @GARROW_TYPE_DECIMAL64: Precision- and scale-based decimal
* type with 64-bit. Storage type depends on the parameters.
*
Expand Down Expand Up @@ -115,8 +116,9 @@ typedef enum {
GARROW_TYPE_LARGE_LIST,
GARROW_TYPE_MONTH_DAY_NANO_INTERVAL,
GARROW_TYPE_RUN_END_ENCODED,
/* TODO: Remove = 44 when we add STRING_VIEW..DECIMAL32. */
GARROW_TYPE_DECIMAL64 = 44,
/* TODO: Remove = 43 when we add STRING_VIEW(39)..LARGE_LIST_VIEW(42). */
GARROW_TYPE_DECIMAL32 = 43,
GARROW_TYPE_DECIMAL64,
} GArrowType;

/**
Expand Down
54 changes: 54 additions & 0 deletions c_glib/test/test-decimal32-data-type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# 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 TestDecimal32DataType < Test::Unit::TestCase
def test_type
data_type = Arrow::Decimal32DataType.new(2, 0)
assert_equal(Arrow::Type::DECIMAL32, data_type.id)
end

def test_name
data_type = Arrow::Decimal32DataType.new(2, 0)
assert_equal("decimal32", data_type.name)
end

def test_to_s
data_type = Arrow::Decimal32DataType.new(2, 0)
assert_equal("decimal32(2, 0)", data_type.to_s)
end

def test_precision
data_type = Arrow::Decimal32DataType.new(8, 2)
assert_equal(8, data_type.precision)
end

def test_scale
data_type = Arrow::Decimal32DataType.new(8, 2)
assert_equal(2, data_type.scale)
end

def test_decimal_data_type_new
assert_equal(Arrow::Decimal32DataType.new(3, 2),
Arrow::DecimalDataType.new(3, 2))
end

def test_invalid_precision
assert_raise(Arrow::Error::Invalid) do
Arrow::Decimal32DataType.new(10, 1)
end
end
end

0 comments on commit 5b68eca

Please sign in to comment.