Skip to content

Commit 5fbefae

Browse files
authored
GH-48492: [GLib][Ruby] Add MapLookupOptions (#48513)
### Rationale for this change The `MapLookupOptions` class is not available in GLib/Ruby, and it is used together with the `map_lookup` compute function. ### What changes are included in this PR? This adds the `MapLookupOptions` class to GLib. ### Are these changes tested? Yes, with Ruby unit tests. ### Are there any user-facing changes? Yes, a new class. * GitHub Issue: #48492 Authored-by: Sten Larsson <[email protected]> Signed-off-by: Sutou Kouhei <[email protected]>
1 parent 3049131 commit 5fbefae

File tree

4 files changed

+308
-0
lines changed

4 files changed

+308
-0
lines changed

c_glib/arrow-glib/compute.cpp

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,9 @@ G_BEGIN_DECLS
279279
* #GArrowListFlattenOptions is a class to customize the `list_flatten`
280280
* function.
281281
*
282+
* #GArrowMapLookupOptions is a class to customize the `map_lookup`
283+
* function.
284+
*
282285
* There are many functions to compute data on an array.
283286
*/
284287

@@ -7498,6 +7501,169 @@ garrow_list_flatten_options_new(void)
74987501
return GARROW_LIST_FLATTEN_OPTIONS(options);
74997502
}
75007503

7504+
typedef struct GArrowMapLookupOptionsPrivate_
7505+
{
7506+
GArrowScalar *query_key;
7507+
} GArrowMapLookupOptionsPrivate;
7508+
7509+
enum {
7510+
PROP_MAP_LOOKUP_OPTIONS_QUERY_KEY = 1,
7511+
PROP_MAP_LOOKUP_OPTIONS_OCCURRENCE,
7512+
};
7513+
7514+
G_DEFINE_TYPE_WITH_PRIVATE(GArrowMapLookupOptions,
7515+
garrow_map_lookup_options,
7516+
GARROW_TYPE_FUNCTION_OPTIONS)
7517+
7518+
#define GARROW_MAP_LOOKUP_OPTIONS_GET_PRIVATE(object) \
7519+
static_cast<GArrowMapLookupOptionsPrivate *>( \
7520+
garrow_map_lookup_options_get_instance_private(GARROW_MAP_LOOKUP_OPTIONS(object)))
7521+
7522+
static void
7523+
garrow_map_lookup_options_dispose(GObject *object)
7524+
{
7525+
auto priv = GARROW_MAP_LOOKUP_OPTIONS_GET_PRIVATE(object);
7526+
7527+
if (priv->query_key) {
7528+
g_object_unref(priv->query_key);
7529+
priv->query_key = NULL;
7530+
}
7531+
7532+
G_OBJECT_CLASS(garrow_map_lookup_options_parent_class)->dispose(object);
7533+
}
7534+
7535+
static void
7536+
garrow_map_lookup_options_set_property(GObject *object,
7537+
guint prop_id,
7538+
const GValue *value,
7539+
GParamSpec *pspec)
7540+
{
7541+
auto priv = GARROW_MAP_LOOKUP_OPTIONS_GET_PRIVATE(object);
7542+
auto options = garrow_map_lookup_options_get_raw(GARROW_MAP_LOOKUP_OPTIONS(object));
7543+
7544+
switch (prop_id) {
7545+
case PROP_MAP_LOOKUP_OPTIONS_QUERY_KEY:
7546+
{
7547+
auto query_key = g_value_get_object(value);
7548+
if (priv->query_key != query_key) {
7549+
if (priv->query_key) {
7550+
g_object_unref(priv->query_key);
7551+
}
7552+
priv->query_key = GARROW_SCALAR(query_key);
7553+
if (priv->query_key) {
7554+
g_object_ref(priv->query_key);
7555+
options->query_key = garrow_scalar_get_raw(priv->query_key);
7556+
} else {
7557+
options->query_key = nullptr;
7558+
}
7559+
}
7560+
}
7561+
break;
7562+
case PROP_MAP_LOOKUP_OPTIONS_OCCURRENCE:
7563+
options->occurrence =
7564+
static_cast<arrow::compute::MapLookupOptions::Occurrence>(g_value_get_enum(value));
7565+
break;
7566+
default:
7567+
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
7568+
break;
7569+
}
7570+
}
7571+
7572+
static void
7573+
garrow_map_lookup_options_get_property(GObject *object,
7574+
guint prop_id,
7575+
GValue *value,
7576+
GParamSpec *pspec)
7577+
{
7578+
auto priv = GARROW_MAP_LOOKUP_OPTIONS_GET_PRIVATE(object);
7579+
auto options = garrow_map_lookup_options_get_raw(GARROW_MAP_LOOKUP_OPTIONS(object));
7580+
7581+
switch (prop_id) {
7582+
case PROP_MAP_LOOKUP_OPTIONS_QUERY_KEY:
7583+
g_value_set_object(value, priv->query_key);
7584+
break;
7585+
case PROP_MAP_LOOKUP_OPTIONS_OCCURRENCE:
7586+
g_value_set_enum(value, static_cast<GArrowMapLookupOccurrence>(options->occurrence));
7587+
break;
7588+
default:
7589+
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
7590+
break;
7591+
}
7592+
}
7593+
7594+
static void
7595+
garrow_map_lookup_options_init(GArrowMapLookupOptions *object)
7596+
{
7597+
auto priv = GARROW_FUNCTION_OPTIONS_GET_PRIVATE(object);
7598+
priv->options = static_cast<arrow::compute::FunctionOptions *>(
7599+
new arrow::compute::MapLookupOptions());
7600+
}
7601+
7602+
static void
7603+
garrow_map_lookup_options_class_init(GArrowMapLookupOptionsClass *klass)
7604+
{
7605+
auto gobject_class = G_OBJECT_CLASS(klass);
7606+
7607+
gobject_class->dispose = garrow_map_lookup_options_dispose;
7608+
gobject_class->set_property = garrow_map_lookup_options_set_property;
7609+
gobject_class->get_property = garrow_map_lookup_options_get_property;
7610+
7611+
arrow::compute::MapLookupOptions options;
7612+
7613+
GParamSpec *spec;
7614+
/**
7615+
* GArrowMapLookupOptions:query-key:
7616+
*
7617+
* The key to lookup in the map.
7618+
*
7619+
* Since: 23.0.0
7620+
*/
7621+
spec = g_param_spec_object("query-key",
7622+
"Query key",
7623+
"The key to lookup in the map",
7624+
GARROW_TYPE_SCALAR,
7625+
static_cast<GParamFlags>(G_PARAM_READWRITE));
7626+
g_object_class_install_property(gobject_class, PROP_MAP_LOOKUP_OPTIONS_QUERY_KEY, spec);
7627+
7628+
/**
7629+
* GArrowMapLookupOptions:occurrence:
7630+
*
7631+
* Whether to return the first, last, or all matching values.
7632+
*
7633+
* Since: 23.0.0
7634+
*/
7635+
spec = g_param_spec_enum("occurrence",
7636+
"Occurrence",
7637+
"Whether to return the first, last, or all matching values",
7638+
GARROW_TYPE_MAP_LOOKUP_OCCURRENCE,
7639+
static_cast<GArrowMapLookupOccurrence>(options.occurrence),
7640+
static_cast<GParamFlags>(G_PARAM_READWRITE));
7641+
g_object_class_install_property(gobject_class,
7642+
PROP_MAP_LOOKUP_OPTIONS_OCCURRENCE,
7643+
spec);
7644+
}
7645+
7646+
/**
7647+
* garrow_map_lookup_options_new:
7648+
* @query_key: (nullable): A #GArrowScalar to be looked up.
7649+
* @occurrence: A #GArrowMapLookupOccurrence.
7650+
*
7651+
* Returns: A newly created #GArrowMapLookupOptions.
7652+
*
7653+
* Since: 23.0.0
7654+
*/
7655+
GArrowMapLookupOptions *
7656+
garrow_map_lookup_options_new(GArrowScalar *query_key,
7657+
GArrowMapLookupOccurrence occurrence)
7658+
{
7659+
return GARROW_MAP_LOOKUP_OPTIONS(g_object_new(GARROW_TYPE_MAP_LOOKUP_OPTIONS,
7660+
"query-key",
7661+
query_key,
7662+
"occurrence",
7663+
occurrence,
7664+
NULL));
7665+
}
7666+
75017667
G_END_DECLS
75027668

75037669
arrow::Result<arrow::FieldRef>
@@ -7677,6 +7843,11 @@ garrow_function_options_new_raw(const arrow::compute::FunctionOptions *arrow_opt
76777843
static_cast<const arrow::compute::ListFlattenOptions *>(arrow_options);
76787844
auto options = garrow_list_flatten_options_new_raw(arrow_list_flatten_options);
76797845
return GARROW_FUNCTION_OPTIONS(options);
7846+
} else if (arrow_type_name == "MapLookupOptions") {
7847+
const auto arrow_map_lookup_options =
7848+
static_cast<const arrow::compute::MapLookupOptions *>(arrow_options);
7849+
auto options = garrow_map_lookup_options_new_raw(arrow_map_lookup_options);
7850+
return GARROW_FUNCTION_OPTIONS(options);
76807851
} else {
76817852
auto options = g_object_new(GARROW_TYPE_FUNCTION_OPTIONS, NULL);
76827853
return GARROW_FUNCTION_OPTIONS(options);
@@ -8370,3 +8541,28 @@ garrow_list_flatten_options_get_raw(GArrowListFlattenOptions *options)
83708541
return static_cast<arrow::compute::ListFlattenOptions *>(
83718542
garrow_function_options_get_raw(GARROW_FUNCTION_OPTIONS(options)));
83728543
}
8544+
8545+
GArrowMapLookupOptions *
8546+
garrow_map_lookup_options_new_raw(const arrow::compute::MapLookupOptions *arrow_options)
8547+
{
8548+
GArrowScalar *query_key = nullptr;
8549+
if (arrow_options->query_key) {
8550+
auto arrow_query_key = arrow_options->query_key;
8551+
query_key = garrow_scalar_new_raw(&arrow_query_key);
8552+
}
8553+
GArrowMapLookupOccurrence occurrence =
8554+
static_cast<GArrowMapLookupOccurrence>(arrow_options->occurrence);
8555+
return GARROW_MAP_LOOKUP_OPTIONS(g_object_new(GARROW_TYPE_MAP_LOOKUP_OPTIONS,
8556+
"query-key",
8557+
query_key,
8558+
"occurrence",
8559+
occurrence,
8560+
NULL));
8561+
}
8562+
8563+
arrow::compute::MapLookupOptions *
8564+
garrow_map_lookup_options_get_raw(GArrowMapLookupOptions *options)
8565+
{
8566+
return static_cast<arrow::compute::MapLookupOptions *>(
8567+
garrow_function_options_get_raw(GARROW_FUNCTION_OPTIONS(options)));
8568+
}

c_glib/arrow-glib/compute.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,4 +1338,38 @@ GARROW_AVAILABLE_IN_23_0
13381338
GArrowListFlattenOptions *
13391339
garrow_list_flatten_options_new(void);
13401340

1341+
/**
1342+
* GArrowMapLookupOccurrence:
1343+
* @GARROW_MAP_LOOKUP_OCCURRENCE_FIRST: Return the first matching value.
1344+
* @GARROW_MAP_LOOKUP_OCCURRENCE_LAST: Return the last matching value.
1345+
* @GARROW_MAP_LOOKUP_OCCURRENCE_ALL: Return all matching values.
1346+
*
1347+
* They correspond to the values of
1348+
* `arrow::compute::MapLookupOptions::Occurrence`.
1349+
*
1350+
* Since: 23.0.0
1351+
*/
1352+
typedef enum {
1353+
GARROW_MAP_LOOKUP_OCCURRENCE_FIRST,
1354+
GARROW_MAP_LOOKUP_OCCURRENCE_LAST,
1355+
GARROW_MAP_LOOKUP_OCCURRENCE_ALL,
1356+
} GArrowMapLookupOccurrence;
1357+
1358+
#define GARROW_TYPE_MAP_LOOKUP_OPTIONS (garrow_map_lookup_options_get_type())
1359+
GARROW_AVAILABLE_IN_23_0
1360+
G_DECLARE_DERIVABLE_TYPE(GArrowMapLookupOptions,
1361+
garrow_map_lookup_options,
1362+
GARROW,
1363+
MAP_LOOKUP_OPTIONS,
1364+
GArrowFunctionOptions)
1365+
struct _GArrowMapLookupOptionsClass
1366+
{
1367+
GArrowFunctionOptionsClass parent_class;
1368+
};
1369+
1370+
GARROW_AVAILABLE_IN_23_0
1371+
GArrowMapLookupOptions *
1372+
garrow_map_lookup_options_new(GArrowScalar *query_key,
1373+
GArrowMapLookupOccurrence occurrence);
1374+
13411375
G_END_DECLS

c_glib/arrow-glib/compute.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,8 @@ garrow_list_flatten_options_new_raw(
226226
const arrow::compute::ListFlattenOptions *arrow_options);
227227
arrow::compute::ListFlattenOptions *
228228
garrow_list_flatten_options_get_raw(GArrowListFlattenOptions *options);
229+
230+
GArrowMapLookupOptions *
231+
garrow_map_lookup_options_new_raw(const arrow::compute::MapLookupOptions *arrow_options);
232+
arrow::compute::MapLookupOptions *
233+
garrow_map_lookup_options_get_raw(GArrowMapLookupOptions *options);
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
class TestMapLookupOptions < Test::Unit::TestCase
19+
include Helper::Buildable
20+
21+
def setup
22+
@query_key = Arrow::Int32Scalar.new(1)
23+
@options = Arrow::MapLookupOptions.new(@query_key,
24+
Arrow::MapLookupOccurrence::FIRST)
25+
end
26+
27+
def test_query_key_property
28+
assert_equal(@query_key, @options.query_key)
29+
new_query_key = Arrow::Int32Scalar.new(2)
30+
@options.query_key = new_query_key
31+
assert_equal(new_query_key, @options.query_key)
32+
end
33+
34+
def test_occurrence_property
35+
assert_equal(Arrow::MapLookupOccurrence::FIRST, @options.occurrence)
36+
@options.occurrence = :last
37+
assert_equal(Arrow::MapLookupOccurrence::LAST, @options.occurrence)
38+
@options.occurrence = :all
39+
assert_equal(Arrow::MapLookupOccurrence::ALL, @options.occurrence)
40+
@options.occurrence = :first
41+
assert_equal(Arrow::MapLookupOccurrence::FIRST, @options.occurrence)
42+
end
43+
44+
def test_map_lookup_function
45+
map_array = build_map_array(Arrow::Int32DataType.new,
46+
Arrow::StringDataType.new,
47+
[[
48+
[1, "first_one"],
49+
[2, "two"],
50+
[1, nil],
51+
[3, "three"],
52+
[1, "second_one"],
53+
[1, "last_one"],
54+
]])
55+
args = [Arrow::ArrayDatum.new(map_array)]
56+
map_lookup_function = Arrow::Function.find("map_lookup")
57+
@options.query_key = Arrow::Int32Scalar.new(1)
58+
59+
@options.occurrence = :first
60+
result = map_lookup_function.execute(args, @options).value
61+
assert_equal(build_string_array(["first_one"]), result)
62+
63+
@options.occurrence = :last
64+
result = map_lookup_function.execute(args, @options).value
65+
assert_equal(build_string_array(["last_one"]), result)
66+
67+
@options.occurrence = :all
68+
result = map_lookup_function.execute(args, @options).value
69+
assert_equal(build_list_array(Arrow::StringDataType.new,
70+
[["first_one", nil, "second_one", "last_one"]]),
71+
result)
72+
end
73+
end

0 commit comments

Comments
 (0)