1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *   http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied.  See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #include <arrow-glib/data-type.hpp>
21 #include <arrow-glib/error.hpp>
22 #include <arrow-glib/field.hpp>
23 
24 #include <gandiva-glib/node.hpp>
25 
26 template <typename Type>
27 const Type &
ggandiva_literal_node_get(GGandivaLiteralNode * node)28 ggandiva_literal_node_get(GGandivaLiteralNode *node)
29 {
30   auto gandiva_literal_node =
31     std::static_pointer_cast<gandiva::LiteralNode>(ggandiva_node_get_raw(GGANDIVA_NODE(node)));
32   return arrow::util::get<Type>(gandiva_literal_node->holder());
33 }
34 
35 G_BEGIN_DECLS
36 
37 /**
38  * SECTION: node
39  * @section_id: node-classes
40  * @title: Node classes
41  * @include: gandiva-glib/gandiva-glib.h
42  *
43  * #GGandivaNode is a base class for a node in the expression tree.
44  *
45  * #GGandivaFieldNode is a class for a node in the expression tree, representing an Arrow field.
46  *
47  * #GGandivaFunctionNode is a class for a node in the expression tree, representing a function.
48  *
49  * #GGandivaLiteralNode is a base class for a node in the expression tree,
50  * representing a literal.
51  *
52  * #GGandivaNullLiteralNode is a class for a node in the expression tree,
53  * representing a null literal.
54  *
55  * #GGandivaBooleanLiteralNode is a class for a node in the expression tree,
56  * representing a boolean literal.
57  *
58  * #GGandivaInt8LiteralNode is a class for a node in the expression tree,
59  * representing a 8-bit integer literal.
60  *
61  * #GGandivaUInt8LiteralNode is a class for a node in the expression tree,
62  * representing a 8-bit unsigned integer literal.
63  *
64  * #GGandivaInt16LiteralNode is a class for a node in the expression tree,
65  * representing a 16-bit integer literal.
66  *
67  * #GGandivaUInt16LiteralNode is a class for a node in the expression tree,
68  * representing a 16-bit unsigned integer literal.
69  *
70  * #GGandivaInt32LiteralNode is a class for a node in the expression tree,
71  * representing a 32-bit integer literal.
72  *
73  * #GGandivaUInt32LiteralNode is a class for a node in the expression tree,
74  * representing a 32-bit unsigned integer literal.
75  *
76  * #GGandivaInt64LiteralNode is a class for a node in the expression tree,
77  * representing a 64-bit integer literal.
78  *
79  * #GGandivaUInt64LiteralNode is a class for a node in the expression tree,
80  * representing a 64-bit unsigned integer literal.
81  *
82  * #GGandivaFloatLiteralNode is a class for a node in the expression tree,
83  * representing a 32-bit floating point literal.
84  *
85  * #GGandivaDoubleLiteralNode is a class for a node in the expression tree,
86  * representing a 64-bit floating point literal.
87  *
88  * #GGandivaBinaryLiteralNode is a class for a node in the expression tree,
89  * representing a binary literal.
90  *
91  * #GGandivaStringLiteralNode is a class for a node in the expression tree,
92  * representing an UTF-8 encoded string literal.
93  *
94  * #GGandivaIfNode is a class for a node in the expression tree, representing an if-else.
95  *
96  * #GGandivaBooleanNode is a class for a node in the expression tree, representing a boolean.
97  *
98  * #GGandivaAndNode is a class for a node in the expression tree, representing an AND.
99  *
100  * #GGandivaOrNode is a class for a node in the expression tree, representing an OR.
101  *
102  * Since: 0.12.0
103  */
104 
105 typedef struct GGandivaNodePrivate_ {
106   std::shared_ptr<gandiva::Node> node;
107   GArrowDataType *return_type;
108 } GGandivaNodePrivate;
109 
110 enum {
111   PROP_NODE = 1,
112   PROP_RETURN_TYPE
113 };
114 
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(GGandivaNode,ggandiva_node,G_TYPE_OBJECT)115 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(GGandivaNode,
116                                     ggandiva_node,
117                                     G_TYPE_OBJECT)
118 
119 #define GGANDIVA_NODE_GET_PRIVATE(object)                       \
120   static_cast<GGandivaNodePrivate *>(                           \
121     ggandiva_node_get_instance_private(                         \
122       GGANDIVA_NODE(object)))
123 
124 static void
125 ggandiva_node_dispose(GObject *object)
126 {
127   auto priv = GGANDIVA_NODE_GET_PRIVATE(object);
128 
129   if (priv->return_type) {
130     g_object_unref(priv->return_type);
131     priv->return_type = nullptr;
132   }
133 
134   G_OBJECT_CLASS(ggandiva_node_parent_class)->dispose(object);
135 }
136 
137 static void
ggandiva_node_finalize(GObject * object)138 ggandiva_node_finalize(GObject *object)
139 {
140   auto priv = GGANDIVA_NODE_GET_PRIVATE(object);
141 
142   priv->node.~shared_ptr();
143 
144   G_OBJECT_CLASS(ggandiva_node_parent_class)->finalize(object);
145 }
146 
147 static void
ggandiva_node_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)148 ggandiva_node_set_property(GObject *object,
149                            guint prop_id,
150                            const GValue *value,
151                            GParamSpec *pspec)
152 {
153   auto priv = GGANDIVA_NODE_GET_PRIVATE(object);
154 
155   switch (prop_id) {
156   case PROP_NODE:
157     priv->node =
158       *static_cast<std::shared_ptr<gandiva::Node> *>(g_value_get_pointer(value));
159     break;
160   case PROP_RETURN_TYPE:
161     priv->return_type = GARROW_DATA_TYPE(g_value_dup_object(value));
162     break;
163   default:
164     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
165     break;
166   }
167 }
168 
169 static void
ggandiva_node_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)170 ggandiva_node_get_property(GObject *object,
171                            guint prop_id,
172                            GValue *value,
173                            GParamSpec *pspec)
174 {
175   auto priv = GGANDIVA_NODE_GET_PRIVATE(object);
176 
177   switch (prop_id) {
178   case PROP_RETURN_TYPE:
179     g_value_set_object(value, priv->return_type);
180     break;
181   default:
182     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
183     break;
184   }
185 }
186 
187 static void
ggandiva_node_init(GGandivaNode * object)188 ggandiva_node_init(GGandivaNode *object)
189 {
190   auto priv = GGANDIVA_NODE_GET_PRIVATE(object);
191   new(&priv->node) std::shared_ptr<gandiva::Node>;
192 }
193 
194 static void
ggandiva_node_class_init(GGandivaNodeClass * klass)195 ggandiva_node_class_init(GGandivaNodeClass *klass)
196 {
197   auto gobject_class = G_OBJECT_CLASS(klass);
198 
199   gobject_class->dispose      = ggandiva_node_dispose;
200   gobject_class->finalize     = ggandiva_node_finalize;
201   gobject_class->set_property = ggandiva_node_set_property;
202   gobject_class->get_property = ggandiva_node_get_property;
203 
204   GParamSpec *spec;
205   spec = g_param_spec_pointer("node",
206                               "Node",
207                               "The raw std::shared<gandiva::Node> *",
208                               static_cast<GParamFlags>(G_PARAM_WRITABLE |
209                                                        G_PARAM_CONSTRUCT_ONLY));
210   g_object_class_install_property(gobject_class, PROP_NODE, spec);
211 
212   spec = g_param_spec_object("return-type",
213                              "Return type",
214                              "The return type",
215                              GARROW_TYPE_DATA_TYPE,
216                              static_cast<GParamFlags>(G_PARAM_READWRITE |
217                                                       G_PARAM_CONSTRUCT_ONLY));
218   g_object_class_install_property(gobject_class, PROP_RETURN_TYPE, spec);
219 }
220 
221 /**
222  * ggandiva_node_to_string:
223  * @node: A #GGandivaNode.
224  *
225  * Returns: (transfer full): The string representation of the node.
226  *
227  *   It should be freed with g_free() when no longer needed.
228  *
229  * Since: 1.0.0
230  */
231 gchar *
ggandiva_node_to_string(GGandivaNode * node)232 ggandiva_node_to_string(GGandivaNode *node)
233 {
234   auto gandiva_node = ggandiva_node_get_raw(node);
235   auto string = gandiva_node->ToString();
236   return g_strndup(string.data(), string.size());
237 }
238 
239 typedef struct GGandivaFieldNodePrivate_ {
240   GArrowField *field;
241 } GGandivaFieldNodePrivate;
242 
243 enum {
244   PROP_FIELD = 1
245 };
246 
G_DEFINE_TYPE_WITH_PRIVATE(GGandivaFieldNode,ggandiva_field_node,GGANDIVA_TYPE_NODE)247 G_DEFINE_TYPE_WITH_PRIVATE(GGandivaFieldNode,
248                            ggandiva_field_node,
249                            GGANDIVA_TYPE_NODE)
250 
251 #define GGANDIVA_FIELD_NODE_GET_PRIVATE(object)                 \
252   static_cast<GGandivaFieldNodePrivate *>(                      \
253     ggandiva_field_node_get_instance_private(                   \
254       GGANDIVA_FIELD_NODE(object)))
255 
256 static void
257 ggandiva_field_node_dispose(GObject *object)
258 {
259   auto priv = GGANDIVA_FIELD_NODE_GET_PRIVATE(object);
260 
261   if (priv->field) {
262     g_object_unref(priv->field);
263     priv->field = nullptr;
264   }
265 
266   G_OBJECT_CLASS(ggandiva_field_node_parent_class)->dispose(object);
267 }
268 
269 static void
ggandiva_field_node_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)270 ggandiva_field_node_set_property(GObject *object,
271                                  guint prop_id,
272                                  const GValue *value,
273                                  GParamSpec *pspec)
274 {
275   auto priv = GGANDIVA_FIELD_NODE_GET_PRIVATE(object);
276 
277   switch (prop_id) {
278   case PROP_FIELD:
279     priv->field = GARROW_FIELD(g_value_dup_object(value));
280     break;
281   default:
282     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
283     break;
284   }
285 }
286 
287 static void
ggandiva_field_node_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)288 ggandiva_field_node_get_property(GObject *object,
289                                  guint prop_id,
290                                  GValue *value,
291                                  GParamSpec *pspec)
292 {
293   auto priv = GGANDIVA_FIELD_NODE_GET_PRIVATE(object);
294 
295   switch (prop_id) {
296   case PROP_FIELD:
297     g_value_set_object(value, priv->field);
298     break;
299   default:
300     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
301     break;
302   }
303 }
304 
305 static void
ggandiva_field_node_init(GGandivaFieldNode * field_node)306 ggandiva_field_node_init(GGandivaFieldNode *field_node)
307 {
308 }
309 
310 static void
ggandiva_field_node_class_init(GGandivaFieldNodeClass * klass)311 ggandiva_field_node_class_init(GGandivaFieldNodeClass *klass)
312 {
313   auto gobject_class = G_OBJECT_CLASS(klass);
314 
315   gobject_class->dispose      = ggandiva_field_node_dispose;
316   gobject_class->set_property = ggandiva_field_node_set_property;
317   gobject_class->get_property = ggandiva_field_node_get_property;
318 
319   GParamSpec *spec;
320   spec = g_param_spec_object("field",
321                              "Field",
322                              "The field",
323                              GARROW_TYPE_FIELD,
324                              static_cast<GParamFlags>(G_PARAM_READWRITE |
325                                                       G_PARAM_CONSTRUCT_ONLY));
326   g_object_class_install_property(gobject_class, PROP_FIELD, spec);
327 }
328 
329 /**
330  * ggandiva_field_node_new:
331  * @field: A #GArrowField.
332  *
333  * Returns: A newly created #GGandivaFieldNode for the given field.
334  *
335  * Since: 0.12.0
336  */
337 GGandivaFieldNode *
ggandiva_field_node_new(GArrowField * field)338 ggandiva_field_node_new(GArrowField *field)
339 {
340   auto arrow_field = garrow_field_get_raw(field);
341   auto gandiva_node = gandiva::TreeExprBuilder::MakeField(arrow_field);
342   return ggandiva_field_node_new_raw(&gandiva_node, field);
343 }
344 
345 
346 typedef struct GGandivaFunctionNodePrivate_ {
347   gchar *name;
348   GList *parameters;
349 } GGandivaFunctionNodePrivate;
350 
351 enum {
352   PROP_NAME = 1
353 };
354 
G_DEFINE_TYPE_WITH_PRIVATE(GGandivaFunctionNode,ggandiva_function_node,GGANDIVA_TYPE_NODE)355 G_DEFINE_TYPE_WITH_PRIVATE(GGandivaFunctionNode,
356                            ggandiva_function_node,
357                            GGANDIVA_TYPE_NODE)
358 
359 #define GGANDIVA_FUNCTION_NODE_GET_PRIVATE(object)      \
360   static_cast<GGandivaFunctionNodePrivate *>(           \
361     ggandiva_function_node_get_instance_private(        \
362       GGANDIVA_FUNCTION_NODE(object)))                  \
363 
364 static void
365 ggandiva_function_node_dispose(GObject *object)
366 {
367   auto priv = GGANDIVA_FUNCTION_NODE_GET_PRIVATE(object);
368 
369   if (priv->parameters) {
370     for (auto node = priv->parameters; node; node = g_list_next(node)) {
371       auto parameter = GGANDIVA_NODE(node->data);
372       g_object_unref(parameter);
373     }
374     g_list_free(priv->parameters);
375     priv->parameters = nullptr;
376   }
377 
378   G_OBJECT_CLASS(ggandiva_function_node_parent_class)->dispose(object);
379 }
380 
381 static void
ggandiva_function_node_finalize(GObject * object)382 ggandiva_function_node_finalize(GObject *object)
383 {
384   auto priv = GGANDIVA_FUNCTION_NODE_GET_PRIVATE(object);
385 
386   g_free(priv->name);
387 
388   G_OBJECT_CLASS(ggandiva_function_node_parent_class)->finalize(object);
389 }
390 
391 static void
ggandiva_function_node_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)392 ggandiva_function_node_set_property(GObject *object,
393                                     guint prop_id,
394                                     const GValue *value,
395                                     GParamSpec *pspec)
396 {
397   auto priv = GGANDIVA_FUNCTION_NODE_GET_PRIVATE(object);
398 
399   switch (prop_id) {
400   case PROP_NAME:
401     priv->name = g_value_dup_string(value);
402     break;
403   default:
404     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
405     break;
406   }
407 }
408 
409 static void
ggandiva_function_node_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)410 ggandiva_function_node_get_property(GObject *object,
411                                     guint prop_id,
412                                     GValue *value,
413                                     GParamSpec *pspec)
414 {
415   auto priv = GGANDIVA_FUNCTION_NODE_GET_PRIVATE(object);
416 
417   switch (prop_id) {
418   case PROP_NAME:
419     g_value_set_string(value, priv->name);
420     break;
421   default:
422     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
423     break;
424   }
425 }
426 
427 static void
ggandiva_function_node_init(GGandivaFunctionNode * function_node)428 ggandiva_function_node_init(GGandivaFunctionNode *function_node)
429 {
430   auto priv = GGANDIVA_FUNCTION_NODE_GET_PRIVATE(function_node);
431   priv->parameters = nullptr;
432 }
433 
434 static void
ggandiva_function_node_class_init(GGandivaFunctionNodeClass * klass)435 ggandiva_function_node_class_init(GGandivaFunctionNodeClass *klass)
436 {
437   auto gobject_class = G_OBJECT_CLASS(klass);
438 
439   gobject_class->dispose      = ggandiva_function_node_dispose;
440   gobject_class->finalize     = ggandiva_function_node_finalize;
441   gobject_class->set_property = ggandiva_function_node_set_property;
442   gobject_class->get_property = ggandiva_function_node_get_property;
443 
444   GParamSpec *spec;
445   spec = g_param_spec_string("name",
446                              "Name",
447                              "The name of the function",
448                              nullptr,
449                              static_cast<GParamFlags>(G_PARAM_READWRITE |
450                                                       G_PARAM_CONSTRUCT_ONLY));
451   g_object_class_install_property(gobject_class, PROP_NAME, spec);
452 }
453 
454 /**
455  * ggandiva_function_node_new:
456  * @name: The name of the function to be called.
457  * @parameters: (element-type GGandivaNode): The parameters of the function call.
458  * @return_type: The return type of the function call.
459  *
460  * Returns: A newly created #GGandivaFunctionNode for the function call.
461  *
462  * Since: 0.12.0
463  */
464 GGandivaFunctionNode *
ggandiva_function_node_new(const gchar * name,GList * parameters,GArrowDataType * return_type)465 ggandiva_function_node_new(const gchar *name,
466                            GList *parameters,
467                            GArrowDataType *return_type)
468 {
469   std::vector<std::shared_ptr<gandiva::Node>> gandiva_nodes;
470   for (auto node = parameters; node; node = g_list_next(node)) {
471     auto gandiva_node = ggandiva_node_get_raw(GGANDIVA_NODE(node->data));
472     gandiva_nodes.push_back(gandiva_node);
473   }
474   auto arrow_return_type = garrow_data_type_get_raw(return_type);
475   auto gandiva_node = gandiva::TreeExprBuilder::MakeFunction(name,
476                                                              gandiva_nodes,
477                                                              arrow_return_type);
478   return ggandiva_function_node_new_raw(&gandiva_node,
479                                         name,
480                                         parameters,
481                                         return_type);
482 }
483 
484 /**
485  * ggandiva_function_node_get_parameters:
486  * @node: A #GGandivaFunctionNode.
487  *
488  * Returns: (transfer none) (element-type GGandivaNode):
489  *   The parameters of the function node.
490  *
491  * Since: 0.12.0
492  */
493 GList *
ggandiva_function_node_get_parameters(GGandivaFunctionNode * node)494 ggandiva_function_node_get_parameters(GGandivaFunctionNode *node)
495 {
496   auto priv = GGANDIVA_FUNCTION_NODE_GET_PRIVATE(node);
497   return priv->parameters;
498 }
499 
500 
G_DEFINE_TYPE(GGandivaLiteralNode,ggandiva_literal_node,GGANDIVA_TYPE_NODE)501 G_DEFINE_TYPE(GGandivaLiteralNode,
502               ggandiva_literal_node,
503               GGANDIVA_TYPE_NODE)
504 
505 static void
506 ggandiva_literal_node_init(GGandivaLiteralNode *literal_node)
507 {
508 }
509 
510 static void
ggandiva_literal_node_class_init(GGandivaLiteralNodeClass * klass)511 ggandiva_literal_node_class_init(GGandivaLiteralNodeClass *klass)
512 {
513 }
514 
515 
G_DEFINE_TYPE(GGandivaNullLiteralNode,ggandiva_null_literal_node,GGANDIVA_TYPE_LITERAL_NODE)516 G_DEFINE_TYPE(GGandivaNullLiteralNode,
517               ggandiva_null_literal_node,
518               GGANDIVA_TYPE_LITERAL_NODE)
519 
520 static void
521 ggandiva_null_literal_node_init(GGandivaNullLiteralNode *null_literal_node)
522 {
523 }
524 
525 static void
ggandiva_null_literal_node_class_init(GGandivaNullLiteralNodeClass * klass)526 ggandiva_null_literal_node_class_init(GGandivaNullLiteralNodeClass *klass)
527 {
528 }
529 
530 /**
531  * ggandiva_null_literal_node_new:
532  * @return_type: A #GArrowDataType.
533  * @error: (nullable): Return location for a #GError or %NULL.
534  *
535  * Returns: (nullable): A newly created #GGandivaNullLiteralNode for
536  *   the type or %NULL on error.
537  *
538  * Since: 0.12.0
539  */
540 GGandivaNullLiteralNode *
ggandiva_null_literal_node_new(GArrowDataType * return_type,GError ** error)541 ggandiva_null_literal_node_new(GArrowDataType *return_type,
542                                GError **error)
543 {
544   auto arrow_return_type = garrow_data_type_get_raw(return_type);
545   auto gandiva_node = gandiva::TreeExprBuilder::MakeNull(arrow_return_type);
546   if (!gandiva_node) {
547     g_set_error(error,
548                 GARROW_ERROR,
549                 GARROW_ERROR_INVALID,
550                 "[gandiva][null-literal-node][new] "
551                 "failed to create: <%s>",
552                 arrow_return_type->ToString().c_str());
553     return NULL;
554   }
555   return GGANDIVA_NULL_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
556                                                                   return_type));
557 }
558 
559 
G_DEFINE_TYPE(GGandivaBooleanLiteralNode,ggandiva_boolean_literal_node,GGANDIVA_TYPE_LITERAL_NODE)560 G_DEFINE_TYPE(GGandivaBooleanLiteralNode,
561               ggandiva_boolean_literal_node,
562               GGANDIVA_TYPE_LITERAL_NODE)
563 
564 static void
565 ggandiva_boolean_literal_node_init(GGandivaBooleanLiteralNode *boolean_literal_node)
566 {
567 }
568 
569 static void
ggandiva_boolean_literal_node_class_init(GGandivaBooleanLiteralNodeClass * klass)570 ggandiva_boolean_literal_node_class_init(GGandivaBooleanLiteralNodeClass *klass)
571 {
572 }
573 
574 /**
575  * ggandiva_boolean_literal_node_new:
576  * @value: The value of the boolean literal.
577  *
578  * Returns: A newly created #GGandivaBooleanLiteralNode.
579  *
580  * Since: 0.12.0
581  */
582 GGandivaBooleanLiteralNode *
ggandiva_boolean_literal_node_new(gboolean value)583 ggandiva_boolean_literal_node_new(gboolean value)
584 {
585   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(static_cast<bool>(value));
586   return GGANDIVA_BOOLEAN_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
587                                                                      NULL));
588 }
589 
590 /**
591  * ggandiva_boolean_literal_node_get_value:
592  * @node: A #GGandivaBooleanLiteralNode.
593  *
594  * Returns: The value of the boolean literal.
595  *
596  * Since: 0.12.0
597  */
598 gboolean
ggandiva_boolean_literal_node_get_value(GGandivaBooleanLiteralNode * node)599 ggandiva_boolean_literal_node_get_value(GGandivaBooleanLiteralNode *node)
600 {
601   auto value = ggandiva_literal_node_get<bool>(GGANDIVA_LITERAL_NODE(node));
602   return static_cast<gboolean>(value);
603 }
604 
605 
G_DEFINE_TYPE(GGandivaInt8LiteralNode,ggandiva_int8_literal_node,GGANDIVA_TYPE_LITERAL_NODE)606 G_DEFINE_TYPE(GGandivaInt8LiteralNode,
607               ggandiva_int8_literal_node,
608               GGANDIVA_TYPE_LITERAL_NODE)
609 
610 static void
611 ggandiva_int8_literal_node_init(GGandivaInt8LiteralNode *int8_literal_node)
612 {
613 }
614 
615 static void
ggandiva_int8_literal_node_class_init(GGandivaInt8LiteralNodeClass * klass)616 ggandiva_int8_literal_node_class_init(GGandivaInt8LiteralNodeClass *klass)
617 {
618 }
619 
620 /**
621  * ggandiva_int8_literal_node_new:
622  * @value: The value of the 8-bit integer literal.
623  *
624  * Returns: A newly created #GGandivaInt8LiteralNode.
625  *
626  * Since: 0.12.0
627  */
628 GGandivaInt8LiteralNode *
ggandiva_int8_literal_node_new(gint8 value)629 ggandiva_int8_literal_node_new(gint8 value)
630 {
631   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(value);
632   return GGANDIVA_INT8_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
633                                                                   NULL));
634 }
635 
636 /**
637  * ggandiva_int8_literal_node_get_value:
638  * @node: A #GGandivaInt8LiteralNode.
639  *
640  * Returns: The value of the 8-bit integer literal.
641  *
642  * Since: 0.12.0
643  */
644 gint8
ggandiva_int8_literal_node_get_value(GGandivaInt8LiteralNode * node)645 ggandiva_int8_literal_node_get_value(GGandivaInt8LiteralNode *node)
646 {
647   return ggandiva_literal_node_get<int8_t>(GGANDIVA_LITERAL_NODE(node));
648 }
649 
650 
G_DEFINE_TYPE(GGandivaUInt8LiteralNode,ggandiva_uint8_literal_node,GGANDIVA_TYPE_LITERAL_NODE)651 G_DEFINE_TYPE(GGandivaUInt8LiteralNode,
652               ggandiva_uint8_literal_node,
653               GGANDIVA_TYPE_LITERAL_NODE)
654 
655 static void
656 ggandiva_uint8_literal_node_init(GGandivaUInt8LiteralNode *uint8_literal_node)
657 {
658 }
659 
660 static void
ggandiva_uint8_literal_node_class_init(GGandivaUInt8LiteralNodeClass * klass)661 ggandiva_uint8_literal_node_class_init(GGandivaUInt8LiteralNodeClass *klass)
662 {
663 }
664 
665 /**
666  * ggandiva_uint8_literal_node_new:
667  * @value: The value of the 8-bit unsigned integer literal.
668  *
669  * Returns: A newly created #GGandivaUInt8LiteralNode.
670  *
671  * Since: 0.12.0
672  */
673 GGandivaUInt8LiteralNode *
ggandiva_uint8_literal_node_new(guint8 value)674 ggandiva_uint8_literal_node_new(guint8 value)
675 {
676   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(value);
677   return GGANDIVA_UINT8_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
678                                                                    NULL));
679 }
680 
681 /**
682  * ggandiva_uint8_literal_node_get_value:
683  * @node: A #GGandivaUInt8LiteralNode.
684  *
685  * Returns: The value of the 8-bit unsigned integer literal.
686  *
687  * Since: 0.12.0
688  */
689 guint8
ggandiva_uint8_literal_node_get_value(GGandivaUInt8LiteralNode * node)690 ggandiva_uint8_literal_node_get_value(GGandivaUInt8LiteralNode *node)
691 {
692   return ggandiva_literal_node_get<uint8_t>(GGANDIVA_LITERAL_NODE(node));
693 }
694 
695 
G_DEFINE_TYPE(GGandivaInt16LiteralNode,ggandiva_int16_literal_node,GGANDIVA_TYPE_LITERAL_NODE)696 G_DEFINE_TYPE(GGandivaInt16LiteralNode,
697               ggandiva_int16_literal_node,
698               GGANDIVA_TYPE_LITERAL_NODE)
699 
700 static void
701 ggandiva_int16_literal_node_init(GGandivaInt16LiteralNode *int16_literal_node)
702 {
703 }
704 
705 static void
ggandiva_int16_literal_node_class_init(GGandivaInt16LiteralNodeClass * klass)706 ggandiva_int16_literal_node_class_init(GGandivaInt16LiteralNodeClass *klass)
707 {
708 }
709 
710 /**
711  * ggandiva_int16_literal_node_new:
712  * @value: The value of the 16-bit integer literal.
713  *
714  * Returns: A newly created #GGandivaInt16LiteralNode.
715  *
716  * Since: 0.12.0
717  */
718 GGandivaInt16LiteralNode *
ggandiva_int16_literal_node_new(gint16 value)719 ggandiva_int16_literal_node_new(gint16 value)
720 {
721   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(value);
722   return GGANDIVA_INT16_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
723                                                                    NULL));
724 }
725 
726 /**
727  * ggandiva_int16_literal_node_get_value:
728  * @node: A #GGandivaInt16LiteralNode.
729  *
730  * Returns: The value of the 16-bit integer literal.
731  *
732  * Since: 0.12.0
733  */
734 gint16
ggandiva_int16_literal_node_get_value(GGandivaInt16LiteralNode * node)735 ggandiva_int16_literal_node_get_value(GGandivaInt16LiteralNode *node)
736 {
737   return ggandiva_literal_node_get<int16_t>(GGANDIVA_LITERAL_NODE(node));
738 }
739 
740 
G_DEFINE_TYPE(GGandivaUInt16LiteralNode,ggandiva_uint16_literal_node,GGANDIVA_TYPE_LITERAL_NODE)741 G_DEFINE_TYPE(GGandivaUInt16LiteralNode,
742               ggandiva_uint16_literal_node,
743               GGANDIVA_TYPE_LITERAL_NODE)
744 
745 static void
746 ggandiva_uint16_literal_node_init(GGandivaUInt16LiteralNode *uint16_literal_node)
747 {
748 }
749 
750 static void
ggandiva_uint16_literal_node_class_init(GGandivaUInt16LiteralNodeClass * klass)751 ggandiva_uint16_literal_node_class_init(GGandivaUInt16LiteralNodeClass *klass)
752 {
753 }
754 
755 /**
756  * ggandiva_uint16_literal_node_new:
757  * @value: The value of the 16-bit unsigned integer literal.
758  *
759  * Returns: A newly created #GGandivaUInt16LiteralNode.
760  *
761  * Since: 0.12.0
762  */
763 GGandivaUInt16LiteralNode *
ggandiva_uint16_literal_node_new(guint16 value)764 ggandiva_uint16_literal_node_new(guint16 value)
765 {
766   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(value);
767   return GGANDIVA_UINT16_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
768                                                                     NULL));
769 }
770 
771 /**
772  * ggandiva_uint16_literal_node_get_value:
773  * @node: A #GGandivaUInt16LiteralNode.
774  *
775  * Returns: The value of the 16-bit unsigned integer literal.
776  *
777  * Since: 0.12.0
778  */
779 guint16
ggandiva_uint16_literal_node_get_value(GGandivaUInt16LiteralNode * node)780 ggandiva_uint16_literal_node_get_value(GGandivaUInt16LiteralNode *node)
781 {
782   return ggandiva_literal_node_get<uint16_t>(GGANDIVA_LITERAL_NODE(node));
783 }
784 
785 
G_DEFINE_TYPE(GGandivaInt32LiteralNode,ggandiva_int32_literal_node,GGANDIVA_TYPE_LITERAL_NODE)786 G_DEFINE_TYPE(GGandivaInt32LiteralNode,
787               ggandiva_int32_literal_node,
788               GGANDIVA_TYPE_LITERAL_NODE)
789 
790 static void
791 ggandiva_int32_literal_node_init(GGandivaInt32LiteralNode *int32_literal_node)
792 {
793 }
794 
795 static void
ggandiva_int32_literal_node_class_init(GGandivaInt32LiteralNodeClass * klass)796 ggandiva_int32_literal_node_class_init(GGandivaInt32LiteralNodeClass *klass)
797 {
798 }
799 
800 /**
801  * ggandiva_int32_literal_node_new:
802  * @value: The value of the 32-bit integer literal.
803  *
804  * Returns: A newly created #GGandivaInt32LiteralNode.
805  *
806  * Since: 0.12.0
807  */
808 GGandivaInt32LiteralNode *
ggandiva_int32_literal_node_new(gint32 value)809 ggandiva_int32_literal_node_new(gint32 value)
810 {
811   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(value);
812   return GGANDIVA_INT32_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
813                                                                    NULL));
814 }
815 
816 /**
817  * ggandiva_int32_literal_node_get_value:
818  * @node: A #GGandivaInt32LiteralNode.
819  *
820  * Returns: The value of the 32-bit integer literal.
821  *
822  * Since: 0.12.0
823  */
824 gint32
ggandiva_int32_literal_node_get_value(GGandivaInt32LiteralNode * node)825 ggandiva_int32_literal_node_get_value(GGandivaInt32LiteralNode *node)
826 {
827   return ggandiva_literal_node_get<int32_t>(GGANDIVA_LITERAL_NODE(node));
828 }
829 
830 
G_DEFINE_TYPE(GGandivaUInt32LiteralNode,ggandiva_uint32_literal_node,GGANDIVA_TYPE_LITERAL_NODE)831 G_DEFINE_TYPE(GGandivaUInt32LiteralNode,
832               ggandiva_uint32_literal_node,
833               GGANDIVA_TYPE_LITERAL_NODE)
834 
835 static void
836 ggandiva_uint32_literal_node_init(GGandivaUInt32LiteralNode *uint32_literal_node)
837 {
838 }
839 
840 static void
ggandiva_uint32_literal_node_class_init(GGandivaUInt32LiteralNodeClass * klass)841 ggandiva_uint32_literal_node_class_init(GGandivaUInt32LiteralNodeClass *klass)
842 {
843 }
844 
845 /**
846  * ggandiva_uint32_literal_node_new:
847  * @value: The value of the 32-bit unsigned integer literal.
848  *
849  * Returns: A newly created #GGandivaUInt32LiteralNode.
850  *
851  * Since: 0.12.0
852  */
853 GGandivaUInt32LiteralNode *
ggandiva_uint32_literal_node_new(guint32 value)854 ggandiva_uint32_literal_node_new(guint32 value)
855 {
856   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(value);
857   return GGANDIVA_UINT32_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
858                                                                     NULL));
859 }
860 
861 /**
862  * ggandiva_uint32_literal_node_get_value:
863  * @node: A #GGandivaUInt32LiteralNode.
864  *
865  * Returns: The value of the 32-bit unsigned integer literal.
866  *
867  * Since: 0.12.0
868  */
869 guint32
ggandiva_uint32_literal_node_get_value(GGandivaUInt32LiteralNode * node)870 ggandiva_uint32_literal_node_get_value(GGandivaUInt32LiteralNode *node)
871 {
872   return ggandiva_literal_node_get<uint32_t>(GGANDIVA_LITERAL_NODE(node));
873 }
874 
875 
G_DEFINE_TYPE(GGandivaInt64LiteralNode,ggandiva_int64_literal_node,GGANDIVA_TYPE_LITERAL_NODE)876 G_DEFINE_TYPE(GGandivaInt64LiteralNode,
877               ggandiva_int64_literal_node,
878               GGANDIVA_TYPE_LITERAL_NODE)
879 
880 static void
881 ggandiva_int64_literal_node_init(GGandivaInt64LiteralNode *int64_literal_node)
882 {
883 }
884 
885 static void
ggandiva_int64_literal_node_class_init(GGandivaInt64LiteralNodeClass * klass)886 ggandiva_int64_literal_node_class_init(GGandivaInt64LiteralNodeClass *klass)
887 {
888 }
889 
890 /**
891  * ggandiva_int64_literal_node_new:
892  * @value: The value of the 64-bit integer literal.
893  *
894  * Returns: A newly created #GGandivaInt64LiteralNode.
895  *
896  * Since: 0.12.0
897  */
898 GGandivaInt64LiteralNode *
ggandiva_int64_literal_node_new(gint64 value)899 ggandiva_int64_literal_node_new(gint64 value)
900 {
901   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(value);
902   return GGANDIVA_INT64_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
903                                                                    NULL));
904 }
905 
906 /**
907  * ggandiva_int64_literal_node_get_value:
908  * @node: A #GGandivaInt64LiteralNode.
909  *
910  * Returns: The value of the 64-bit integer literal.
911  *
912  * Since: 0.12.0
913  */
914 gint64
ggandiva_int64_literal_node_get_value(GGandivaInt64LiteralNode * node)915 ggandiva_int64_literal_node_get_value(GGandivaInt64LiteralNode *node)
916 {
917   return ggandiva_literal_node_get<int64_t>(GGANDIVA_LITERAL_NODE(node));
918 }
919 
920 
G_DEFINE_TYPE(GGandivaUInt64LiteralNode,ggandiva_uint64_literal_node,GGANDIVA_TYPE_LITERAL_NODE)921 G_DEFINE_TYPE(GGandivaUInt64LiteralNode,
922               ggandiva_uint64_literal_node,
923               GGANDIVA_TYPE_LITERAL_NODE)
924 
925 static void
926 ggandiva_uint64_literal_node_init(GGandivaUInt64LiteralNode *uint64_literal_node)
927 {
928 }
929 
930 static void
ggandiva_uint64_literal_node_class_init(GGandivaUInt64LiteralNodeClass * klass)931 ggandiva_uint64_literal_node_class_init(GGandivaUInt64LiteralNodeClass *klass)
932 {
933 }
934 
935 /**
936  * ggandiva_uint64_literal_node_new:
937  * @value: The value of the 64-bit unsigned integer literal.
938  *
939  * Returns: A newly created #GGandivaUInt64LiteralNode.
940  *
941  * Since: 0.12.0
942  */
943 GGandivaUInt64LiteralNode *
ggandiva_uint64_literal_node_new(guint64 value)944 ggandiva_uint64_literal_node_new(guint64 value)
945 {
946   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(value);
947   return GGANDIVA_UINT64_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
948                                                                     NULL));
949 }
950 
951 /**
952  * ggandiva_uint64_literal_node_get_value:
953  * @node: A #GGandivaUInt64LiteralNode.
954  *
955  * Returns: The value of the 64-bit unsigned integer literal.
956  *
957  * Since: 0.12.0
958  */
959 guint64
ggandiva_uint64_literal_node_get_value(GGandivaUInt64LiteralNode * node)960 ggandiva_uint64_literal_node_get_value(GGandivaUInt64LiteralNode *node)
961 {
962   return ggandiva_literal_node_get<uint64_t>(GGANDIVA_LITERAL_NODE(node));
963 }
964 
965 
G_DEFINE_TYPE(GGandivaFloatLiteralNode,ggandiva_float_literal_node,GGANDIVA_TYPE_LITERAL_NODE)966 G_DEFINE_TYPE(GGandivaFloatLiteralNode,
967               ggandiva_float_literal_node,
968               GGANDIVA_TYPE_LITERAL_NODE)
969 
970 static void
971 ggandiva_float_literal_node_init(GGandivaFloatLiteralNode *float_literal_node)
972 {
973 }
974 
975 static void
ggandiva_float_literal_node_class_init(GGandivaFloatLiteralNodeClass * klass)976 ggandiva_float_literal_node_class_init(GGandivaFloatLiteralNodeClass *klass)
977 {
978 }
979 
980 /**
981  * ggandiva_float_literal_node_new:
982  * @value: The value of the 32-bit floating point literal.
983  *
984  * Returns: A newly created #GGandivaFloatLiteralNode.
985  *
986  * Since: 0.12.0
987  */
988 GGandivaFloatLiteralNode *
ggandiva_float_literal_node_new(gfloat value)989 ggandiva_float_literal_node_new(gfloat value)
990 {
991   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(value);
992   return GGANDIVA_FLOAT_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
993                                                                    NULL));
994 }
995 
996 /**
997  * ggandiva_float_literal_node_get_value:
998  * @node: A #GGandivaFloatLiteralNode.
999  *
1000  * Returns: The value of the 32-bit floating point literal.
1001  *
1002  * Since: 0.12.0
1003  */
1004 gfloat
ggandiva_float_literal_node_get_value(GGandivaFloatLiteralNode * node)1005 ggandiva_float_literal_node_get_value(GGandivaFloatLiteralNode *node)
1006 {
1007   return ggandiva_literal_node_get<float>(GGANDIVA_LITERAL_NODE(node));
1008 }
1009 
1010 
G_DEFINE_TYPE(GGandivaDoubleLiteralNode,ggandiva_double_literal_node,GGANDIVA_TYPE_LITERAL_NODE)1011 G_DEFINE_TYPE(GGandivaDoubleLiteralNode,
1012               ggandiva_double_literal_node,
1013               GGANDIVA_TYPE_LITERAL_NODE)
1014 
1015 static void
1016 ggandiva_double_literal_node_init(GGandivaDoubleLiteralNode *double_literal_node)
1017 {
1018 }
1019 
1020 static void
ggandiva_double_literal_node_class_init(GGandivaDoubleLiteralNodeClass * klass)1021 ggandiva_double_literal_node_class_init(GGandivaDoubleLiteralNodeClass *klass)
1022 {
1023 }
1024 
1025 /**
1026  * ggandiva_double_literal_node_new:
1027  * @value: The value of the 64-bit floating point literal.
1028  *
1029  * Returns: A newly created #GGandivaDoubleLiteralNode.
1030  *
1031  * Since: 0.12.0
1032  */
1033 GGandivaDoubleLiteralNode *
ggandiva_double_literal_node_new(gdouble value)1034 ggandiva_double_literal_node_new(gdouble value)
1035 {
1036   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(value);
1037   return GGANDIVA_DOUBLE_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
1038                                                                     NULL));
1039 }
1040 
1041 /**
1042  * ggandiva_double_literal_node_get_value:
1043  * @node: A #GGandivaDoubleLiteralNode.
1044  *
1045  * Returns: The value of the 64-bit floating point literal.
1046  *
1047  * Since: 0.12.0
1048  */
1049 gdouble
ggandiva_double_literal_node_get_value(GGandivaDoubleLiteralNode * node)1050 ggandiva_double_literal_node_get_value(GGandivaDoubleLiteralNode *node)
1051 {
1052   return ggandiva_literal_node_get<double>(GGANDIVA_LITERAL_NODE(node));
1053 }
1054 
1055 
1056 typedef struct GGandivaBinaryLiteralNodePrivate_ {
1057   GBytes *value;
1058 } GGandivaBinaryLiteralNodePrivate;
1059 
G_DEFINE_TYPE_WITH_PRIVATE(GGandivaBinaryLiteralNode,ggandiva_binary_literal_node,GGANDIVA_TYPE_LITERAL_NODE)1060 G_DEFINE_TYPE_WITH_PRIVATE(GGandivaBinaryLiteralNode,
1061                            ggandiva_binary_literal_node,
1062                            GGANDIVA_TYPE_LITERAL_NODE)
1063 
1064 #define GGANDIVA_BINARY_LITERAL_NODE_GET_PRIVATE(object)                \
1065   static_cast<GGandivaBinaryLiteralNodePrivate *>(                      \
1066     ggandiva_binary_literal_node_get_instance_private(                  \
1067       GGANDIVA_BINARY_LITERAL_NODE(object)))
1068 
1069 static void
1070 ggandiva_binary_literal_node_dispose(GObject *object)
1071 {
1072   auto priv = GGANDIVA_BINARY_LITERAL_NODE_GET_PRIVATE(object);
1073 
1074   if (priv->value) {
1075     g_bytes_unref(priv->value);
1076     priv->value = nullptr;
1077   }
1078 
1079   G_OBJECT_CLASS(ggandiva_binary_literal_node_parent_class)->dispose(object);
1080 }
1081 
1082 static void
ggandiva_binary_literal_node_init(GGandivaBinaryLiteralNode * binary_literal_node)1083 ggandiva_binary_literal_node_init(GGandivaBinaryLiteralNode *binary_literal_node)
1084 {
1085 }
1086 
1087 static void
ggandiva_binary_literal_node_class_init(GGandivaBinaryLiteralNodeClass * klass)1088 ggandiva_binary_literal_node_class_init(GGandivaBinaryLiteralNodeClass *klass)
1089 {
1090   auto gobject_class = G_OBJECT_CLASS(klass);
1091 
1092   gobject_class->dispose = ggandiva_binary_literal_node_dispose;
1093 }
1094 
1095 /**
1096  * ggandiva_binary_literal_node_new:
1097  * @value: (array length=size): The value of the binary literal.
1098  * @size: The number of bytes of the value.
1099  *
1100  * Returns: A newly created #GGandivaBinaryLiteralNode.
1101  *
1102  * Since: 0.12.0
1103  */
1104 GGandivaBinaryLiteralNode *
ggandiva_binary_literal_node_new(const guint8 * value,gsize size)1105 ggandiva_binary_literal_node_new(const guint8 *value,
1106                                  gsize size)
1107 {
1108   auto gandiva_node =
1109     gandiva::TreeExprBuilder::MakeBinaryLiteral(std::string(reinterpret_cast<const char *>(value),
1110                                                             size));
1111   return GGANDIVA_BINARY_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
1112                                                                     NULL));
1113 }
1114 
1115 /**
1116  * ggandiva_binary_literal_node_new_bytes:
1117  * @value: The value of the binary literal.
1118  *
1119  * Returns: A newly created #GGandivaBinaryLiteralNode.
1120  *
1121  * Since: 0.12.0
1122  */
1123 GGandivaBinaryLiteralNode *
ggandiva_binary_literal_node_new_bytes(GBytes * value)1124 ggandiva_binary_literal_node_new_bytes(GBytes *value)
1125 {
1126   size_t value_size;
1127   auto raw_value = g_bytes_get_data(value, &value_size);
1128   auto gandiva_node =
1129     gandiva::TreeExprBuilder::MakeBinaryLiteral(
1130       std::string(reinterpret_cast<const char *>(raw_value),
1131                   value_size));
1132   auto literal_node = ggandiva_literal_node_new_raw(&gandiva_node,
1133                                                     NULL);
1134   auto priv = GGANDIVA_BINARY_LITERAL_NODE_GET_PRIVATE(literal_node);
1135   priv->value = value;
1136   g_bytes_ref(priv->value);
1137   return GGANDIVA_BINARY_LITERAL_NODE(literal_node);
1138 }
1139 
1140 /**
1141  * ggandiva_binary_literal_node_get_value:
1142  * @node: A #GGandivaBinaryLiteralNode.
1143  *
1144  * Returns: (transfer none): The value of the binary literal.
1145  *
1146  * Since: 0.12.0
1147  */
1148 GBytes *
ggandiva_binary_literal_node_get_value(GGandivaBinaryLiteralNode * node)1149 ggandiva_binary_literal_node_get_value(GGandivaBinaryLiteralNode *node)
1150 {
1151   auto priv = GGANDIVA_BINARY_LITERAL_NODE_GET_PRIVATE(node);
1152   if (!priv->value) {
1153     auto value = ggandiva_literal_node_get<std::string>(GGANDIVA_LITERAL_NODE(node));
1154     priv->value = g_bytes_new(value.data(), value.size());
1155   }
1156 
1157   return priv->value;
1158 }
1159 
1160 
G_DEFINE_TYPE(GGandivaStringLiteralNode,ggandiva_string_literal_node,GGANDIVA_TYPE_LITERAL_NODE)1161 G_DEFINE_TYPE(GGandivaStringLiteralNode,
1162               ggandiva_string_literal_node,
1163               GGANDIVA_TYPE_LITERAL_NODE)
1164 
1165 static void
1166 ggandiva_string_literal_node_init(GGandivaStringLiteralNode *string_literal_node)
1167 {
1168 }
1169 
1170 static void
ggandiva_string_literal_node_class_init(GGandivaStringLiteralNodeClass * klass)1171 ggandiva_string_literal_node_class_init(GGandivaStringLiteralNodeClass *klass)
1172 {
1173 }
1174 
1175 /**
1176  * ggandiva_string_literal_node_new:
1177  * @value: The value of the UTF-8 encoded string literal.
1178  *
1179  * Returns: A newly created #GGandivaStringLiteralNode.
1180  *
1181  * Since: 0.12.0
1182  */
1183 GGandivaStringLiteralNode *
ggandiva_string_literal_node_new(const gchar * value)1184 ggandiva_string_literal_node_new(const gchar *value)
1185 {
1186   auto gandiva_node = gandiva::TreeExprBuilder::MakeStringLiteral(value);
1187   return GGANDIVA_STRING_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
1188                                                                     NULL));
1189 }
1190 
1191 /**
1192  * ggandiva_string_literal_node_get_value:
1193  * @node: A #GGandivaStringLiteralNode.
1194  *
1195  * Returns: The value of the UTF-8 encoded string literal.
1196  *
1197  * Since: 0.12.0
1198  */
1199 const gchar *
ggandiva_string_literal_node_get_value(GGandivaStringLiteralNode * node)1200 ggandiva_string_literal_node_get_value(GGandivaStringLiteralNode *node)
1201 {
1202   auto &value = ggandiva_literal_node_get<std::string>(GGANDIVA_LITERAL_NODE(node));
1203   return value.c_str();
1204 }
1205 
1206 
1207 typedef struct GGandivaIfNodePrivate_ {
1208   GGandivaNode *condition_node;
1209   GGandivaNode *then_node;
1210   GGandivaNode *else_node;
1211 } GGandivaIfNodePrivate;
1212 
1213 enum {
1214   PROP_CONDITION_NODE = 1,
1215   PROP_THEN_NODE,
1216   PROP_ELSE_NODE,
1217 };
1218 
G_DEFINE_TYPE_WITH_PRIVATE(GGandivaIfNode,ggandiva_if_node,GGANDIVA_TYPE_NODE)1219 G_DEFINE_TYPE_WITH_PRIVATE(GGandivaIfNode,
1220                            ggandiva_if_node,
1221                            GGANDIVA_TYPE_NODE)
1222 
1223 #define GGANDIVA_IF_NODE_GET_PRIVATE(object)                 \
1224   static_cast<GGandivaIfNodePrivate *>(                      \
1225     ggandiva_if_node_get_instance_private(                   \
1226       GGANDIVA_IF_NODE(object)))
1227 
1228 static void
1229 ggandiva_if_node_dispose(GObject *object)
1230 {
1231   auto priv = GGANDIVA_IF_NODE_GET_PRIVATE(object);
1232 
1233   if (priv->condition_node) {
1234     g_object_unref(priv->condition_node);
1235     priv->condition_node = nullptr;
1236   }
1237 
1238   if (priv->then_node) {
1239     g_object_unref(priv->then_node);
1240     priv->then_node = nullptr;
1241   }
1242 
1243   if (priv->else_node) {
1244     g_object_unref(priv->else_node);
1245     priv->else_node = nullptr;
1246   }
1247 
1248   G_OBJECT_CLASS(ggandiva_if_node_parent_class)->dispose(object);
1249 }
1250 
1251 static void
ggandiva_if_node_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)1252 ggandiva_if_node_set_property(GObject *object,
1253                               guint prop_id,
1254                               const GValue *value,
1255                               GParamSpec *pspec)
1256 {
1257   auto priv = GGANDIVA_IF_NODE_GET_PRIVATE(object);
1258 
1259   switch (prop_id) {
1260   case PROP_CONDITION_NODE:
1261     priv->condition_node = GGANDIVA_NODE(g_value_dup_object(value));
1262     break;
1263   case PROP_THEN_NODE:
1264     priv->then_node = GGANDIVA_NODE(g_value_dup_object(value));
1265     break;
1266   case PROP_ELSE_NODE:
1267     priv->else_node = GGANDIVA_NODE(g_value_dup_object(value));
1268     break;
1269   default:
1270     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
1271     break;
1272   }
1273 }
1274 
1275 static void
ggandiva_if_node_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)1276 ggandiva_if_node_get_property(GObject *object,
1277                               guint prop_id,
1278                               GValue *value,
1279                               GParamSpec *pspec)
1280 {
1281   auto priv = GGANDIVA_IF_NODE_GET_PRIVATE(object);
1282 
1283   switch (prop_id) {
1284   case PROP_CONDITION_NODE:
1285     g_value_set_object(value, priv->condition_node);
1286     break;
1287   case PROP_THEN_NODE:
1288     g_value_set_object(value, priv->then_node);
1289     break;
1290   case PROP_ELSE_NODE:
1291     g_value_set_object(value, priv->else_node);
1292     break;
1293   default:
1294     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
1295     break;
1296   }
1297 }
1298 
1299 static void
ggandiva_if_node_init(GGandivaIfNode * if_node)1300 ggandiva_if_node_init(GGandivaIfNode *if_node)
1301 {
1302 }
1303 
1304 static void
ggandiva_if_node_class_init(GGandivaIfNodeClass * klass)1305 ggandiva_if_node_class_init(GGandivaIfNodeClass *klass)
1306 {
1307   auto gobject_class = G_OBJECT_CLASS(klass);
1308 
1309   gobject_class->dispose      = ggandiva_if_node_dispose;
1310   gobject_class->set_property = ggandiva_if_node_set_property;
1311   gobject_class->get_property = ggandiva_if_node_get_property;
1312 
1313   GParamSpec *spec;
1314   spec = g_param_spec_object("condition-node",
1315                              "Condition node",
1316                              "The condition node",
1317                              GGANDIVA_TYPE_NODE,
1318                              static_cast<GParamFlags>(G_PARAM_READWRITE |
1319                                                       G_PARAM_CONSTRUCT_ONLY));
1320   g_object_class_install_property(gobject_class, PROP_CONDITION_NODE, spec);
1321 
1322   spec = g_param_spec_object("then-node",
1323                              "Then node",
1324                              "The then node",
1325                              GGANDIVA_TYPE_NODE,
1326                              static_cast<GParamFlags>(G_PARAM_READWRITE |
1327                                                       G_PARAM_CONSTRUCT_ONLY));
1328   g_object_class_install_property(gobject_class, PROP_THEN_NODE, spec);
1329 
1330   spec = g_param_spec_object("else-node",
1331                              "Else node",
1332                              "The else node",
1333                              GGANDIVA_TYPE_NODE,
1334                              static_cast<GParamFlags>(G_PARAM_READWRITE |
1335                                                       G_PARAM_CONSTRUCT_ONLY));
1336   g_object_class_install_property(gobject_class, PROP_ELSE_NODE, spec);
1337 }
1338 
1339 /**
1340  * ggandiva_if_node_new:
1341  * @condition_node: the node with the condition for if-else expression.
1342  * @then_node: the node in case the condition node is true.
1343  * @else_node: the node in case the condition node is false.
1344  * @return_type: A #GArrowDataType.
1345  * @error: (nullable): Return location for a #GError or %NULL.
1346  *
1347  * Returns: (nullable): A newly created #GGandivaIfNode or %NULL on error.
1348  *
1349  * Since: 0.12.0
1350  */
1351 GGandivaIfNode *
ggandiva_if_node_new(GGandivaNode * condition_node,GGandivaNode * then_node,GGandivaNode * else_node,GArrowDataType * return_type,GError ** error)1352 ggandiva_if_node_new(GGandivaNode *condition_node,
1353                      GGandivaNode *then_node,
1354                      GGandivaNode *else_node,
1355                      GArrowDataType *return_type,
1356                      GError **error)
1357 {
1358   if (!condition_node || !then_node || !else_node || !return_type) {
1359     /* TODO: Improve error message to show which arguments are invalid. */
1360     g_set_error(error,
1361                 GARROW_ERROR,
1362                 GARROW_ERROR_INVALID,
1363                 "[gandiva][if-literal-node][new] "
1364                 "all arguments must not NULL");
1365     return NULL;
1366   }
1367   auto gandiva_condition_node = ggandiva_node_get_raw(condition_node);
1368   auto gandiva_then_node = ggandiva_node_get_raw(then_node);
1369   auto gandiva_else_node = ggandiva_node_get_raw(else_node);
1370   auto arrow_return_type = garrow_data_type_get_raw(return_type);
1371   auto gandiva_node = gandiva::TreeExprBuilder::MakeIf(gandiva_condition_node,
1372                                                        gandiva_then_node,
1373                                                        gandiva_else_node,
1374                                                        arrow_return_type);
1375   if (!gandiva_node) {
1376     g_set_error(error,
1377                 GARROW_ERROR,
1378                 GARROW_ERROR_INVALID,
1379                 "[gandiva][if-literal-node][new] "
1380                 "failed to create: if (<%s>) {<%s>} else {<%s>} -> <%s>",
1381                 gandiva_condition_node->ToString().c_str(),
1382                 gandiva_then_node->ToString().c_str(),
1383                 gandiva_else_node->ToString().c_str(),
1384                 arrow_return_type->ToString().c_str());
1385     return NULL;
1386   }
1387   return ggandiva_if_node_new_raw(&gandiva_node,
1388                                   condition_node,
1389                                   then_node,
1390                                   else_node,
1391                                   return_type);
1392 }
1393 
1394 
1395 typedef struct GGandivaBooleanNodePrivate_ {
1396   GList *children;
1397 } GGandivaBooleanNodePrivate;
1398 
G_DEFINE_TYPE_WITH_PRIVATE(GGandivaBooleanNode,ggandiva_boolean_node,GGANDIVA_TYPE_NODE)1399 G_DEFINE_TYPE_WITH_PRIVATE(GGandivaBooleanNode,
1400                            ggandiva_boolean_node,
1401                            GGANDIVA_TYPE_NODE)
1402 
1403 #define GGANDIVA_BOOLEAN_NODE_GET_PRIVATE(object)      \
1404   static_cast<GGandivaBooleanNodePrivate *>(           \
1405     ggandiva_boolean_node_get_instance_private(        \
1406       GGANDIVA_BOOLEAN_NODE(object)))                  \
1407 
1408 static void
1409 ggandiva_boolean_node_dispose(GObject *object)
1410 {
1411   auto priv = GGANDIVA_BOOLEAN_NODE_GET_PRIVATE(object);
1412 
1413   if (priv->children) {
1414     g_list_free_full(priv->children, g_object_unref);
1415     priv->children = nullptr;
1416   }
1417 
1418   G_OBJECT_CLASS(ggandiva_boolean_node_parent_class)->dispose(object);
1419 }
1420 
1421 static void
ggandiva_boolean_node_init(GGandivaBooleanNode * boolean_node)1422 ggandiva_boolean_node_init(GGandivaBooleanNode *boolean_node)
1423 {
1424   auto priv = GGANDIVA_BOOLEAN_NODE_GET_PRIVATE(boolean_node);
1425   priv->children = nullptr;
1426 }
1427 
1428 static void
ggandiva_boolean_node_class_init(GGandivaBooleanNodeClass * klass)1429 ggandiva_boolean_node_class_init(GGandivaBooleanNodeClass *klass)
1430 {
1431   auto gobject_class = G_OBJECT_CLASS(klass);
1432 
1433   gobject_class->dispose = ggandiva_boolean_node_dispose;
1434 }
1435 
1436 /**
1437  * ggandiva_boolean_node_get_children:
1438  * @node: A #GGandivaBooleanNode.
1439  *
1440  * Returns: (transfer none) (element-type GGandivaNode):
1441  *   The children of the boolean node.
1442  *
1443  * Since: 0.17.0
1444  */
1445 GList *
ggandiva_boolean_node_get_children(GGandivaBooleanNode * node)1446 ggandiva_boolean_node_get_children(GGandivaBooleanNode *node)
1447 {
1448   auto priv = GGANDIVA_BOOLEAN_NODE_GET_PRIVATE(node);
1449   return priv->children;
1450 }
1451 
1452 
G_DEFINE_TYPE(GGandivaAndNode,ggandiva_and_node,GGANDIVA_TYPE_BOOLEAN_NODE)1453 G_DEFINE_TYPE(GGandivaAndNode,
1454               ggandiva_and_node,
1455               GGANDIVA_TYPE_BOOLEAN_NODE)
1456 
1457 static void
1458 ggandiva_and_node_init(GGandivaAndNode *and_node)
1459 {
1460 }
1461 
1462 static void
ggandiva_and_node_class_init(GGandivaAndNodeClass * klass)1463 ggandiva_and_node_class_init(GGandivaAndNodeClass *klass)
1464 {
1465 }
1466 
1467 /**
1468  * ggandiva_and_node_new:
1469  * @children: (element-type GGandivaNode): The children of the AND node.
1470  *
1471  * Returns: A newly created #GGandivaAndNode for the AND expression.
1472  *
1473  * Since: 0.17.0
1474  */
1475 GGandivaAndNode *
ggandiva_and_node_new(GList * children)1476 ggandiva_and_node_new(GList *children)
1477 {
1478   std::vector<std::shared_ptr<gandiva::Node>> gandiva_nodes;
1479   for (auto node = children; node; node = g_list_next(node)) {
1480     auto gandiva_node = ggandiva_node_get_raw(GGANDIVA_NODE(node->data));
1481     gandiva_nodes.push_back(gandiva_node);
1482   }
1483   auto gandiva_node = gandiva::TreeExprBuilder::MakeAnd(gandiva_nodes);
1484   return GGANDIVA_AND_NODE(ggandiva_boolean_node_new_raw(&gandiva_node,
1485                                                          children));
1486 }
1487 
1488 
G_DEFINE_TYPE(GGandivaOrNode,ggandiva_or_node,GGANDIVA_TYPE_BOOLEAN_NODE)1489 G_DEFINE_TYPE(GGandivaOrNode,
1490               ggandiva_or_node,
1491               GGANDIVA_TYPE_BOOLEAN_NODE)
1492 
1493 static void
1494 ggandiva_or_node_init(GGandivaOrNode *or_node)
1495 {
1496 }
1497 
1498 static void
ggandiva_or_node_class_init(GGandivaOrNodeClass * klass)1499 ggandiva_or_node_class_init(GGandivaOrNodeClass *klass)
1500 {
1501 }
1502 
1503 /**
1504  * ggandiva_or_node_new:
1505  * @children: (element-type GGandivaNode): The children of the OR node.
1506  *
1507  * Returns: A newly created #GGandivaOrNode for the OR expression.
1508  *
1509  * Since: 0.17.0
1510  */
1511 GGandivaOrNode *
ggandiva_or_node_new(GList * children)1512 ggandiva_or_node_new(GList *children)
1513 {
1514   std::vector<std::shared_ptr<gandiva::Node>> gandiva_nodes;
1515   for (auto node = children; node; node = g_list_next(node)) {
1516     auto gandiva_node = ggandiva_node_get_raw(GGANDIVA_NODE(node->data));
1517     gandiva_nodes.push_back(gandiva_node);
1518   }
1519   auto gandiva_node = gandiva::TreeExprBuilder::MakeOr(gandiva_nodes);
1520   return GGANDIVA_OR_NODE(ggandiva_boolean_node_new_raw(&gandiva_node,
1521                                                         children));
1522 }
1523 
1524 G_END_DECLS
1525 
1526 std::shared_ptr<gandiva::Node>
ggandiva_node_get_raw(GGandivaNode * node)1527 ggandiva_node_get_raw(GGandivaNode *node)
1528 {
1529   auto priv = GGANDIVA_NODE_GET_PRIVATE(node);
1530   return priv->node;
1531 }
1532 
1533 GGandivaFieldNode *
ggandiva_field_node_new_raw(std::shared_ptr<gandiva::Node> * gandiva_node,GArrowField * field)1534 ggandiva_field_node_new_raw(std::shared_ptr<gandiva::Node> *gandiva_node,
1535                             GArrowField *field)
1536 {
1537   auto arrow_return_type = (*gandiva_node)->return_type();
1538   auto return_type = garrow_field_get_data_type(field);
1539   auto field_node = g_object_new(GGANDIVA_TYPE_FIELD_NODE,
1540                                  "node", gandiva_node,
1541                                  "field", field,
1542                                  "return-type", return_type,
1543                                  NULL);
1544   return GGANDIVA_FIELD_NODE(field_node);
1545 }
1546 
1547 GGandivaFunctionNode *
ggandiva_function_node_new_raw(std::shared_ptr<gandiva::Node> * gandiva_node,const gchar * name,GList * parameters,GArrowDataType * return_type)1548 ggandiva_function_node_new_raw(std::shared_ptr<gandiva::Node> *gandiva_node,
1549                                const gchar *name,
1550                                GList *parameters,
1551                                GArrowDataType *return_type)
1552 {
1553   auto function_node = g_object_new(GGANDIVA_TYPE_FUNCTION_NODE,
1554                                     "node", gandiva_node,
1555                                     "name", name,
1556                                     "return-type", return_type,
1557                                     NULL);
1558   auto priv = GGANDIVA_FUNCTION_NODE_GET_PRIVATE(function_node);
1559   for (auto node = parameters; node; node = g_list_next(node)) {
1560     auto parameter = GGANDIVA_NODE(node->data);
1561     priv->parameters = g_list_prepend(priv->parameters, g_object_ref(parameter));
1562   }
1563   priv->parameters = g_list_reverse(priv->parameters);
1564   return GGANDIVA_FUNCTION_NODE(function_node);
1565 }
1566 
1567 GGandivaLiteralNode *
ggandiva_literal_node_new_raw(std::shared_ptr<gandiva::Node> * gandiva_node,GArrowDataType * return_type)1568 ggandiva_literal_node_new_raw(std::shared_ptr<gandiva::Node> *gandiva_node,
1569                               GArrowDataType *return_type)
1570 {
1571   auto gandiva_literal_node =
1572     std::static_pointer_cast<gandiva::LiteralNode>(*gandiva_node);
1573 
1574   GGandivaLiteralNode *literal_node;
1575   if (gandiva_literal_node->is_null()) {
1576     literal_node =
1577       GGANDIVA_LITERAL_NODE(g_object_new(GGANDIVA_TYPE_NULL_LITERAL_NODE,
1578                                          "node", gandiva_node,
1579                                          "return-type", return_type,
1580                                          NULL));
1581   } else {
1582     GType type;
1583 
1584     auto arrow_return_type = gandiva_literal_node->return_type();
1585     switch (arrow_return_type->id()) {
1586     case arrow::Type::BOOL:
1587       type = GGANDIVA_TYPE_BOOLEAN_LITERAL_NODE;
1588       break;
1589     case arrow::Type::type::UINT8:
1590       type = GGANDIVA_TYPE_UINT8_LITERAL_NODE;
1591       break;
1592     case arrow::Type::type::UINT16:
1593       type = GGANDIVA_TYPE_UINT16_LITERAL_NODE;
1594       break;
1595     case arrow::Type::type::UINT32:
1596       type = GGANDIVA_TYPE_UINT32_LITERAL_NODE;
1597       break;
1598     case arrow::Type::type::UINT64:
1599       type = GGANDIVA_TYPE_UINT64_LITERAL_NODE;
1600       break;
1601     case arrow::Type::type::INT8:
1602       type = GGANDIVA_TYPE_INT8_LITERAL_NODE;
1603       break;
1604     case arrow::Type::type::INT16:
1605       type = GGANDIVA_TYPE_INT16_LITERAL_NODE;
1606       break;
1607     case arrow::Type::type::INT32:
1608       type = GGANDIVA_TYPE_INT32_LITERAL_NODE;
1609       break;
1610     case arrow::Type::type::INT64:
1611       type = GGANDIVA_TYPE_INT64_LITERAL_NODE;
1612       break;
1613     case arrow::Type::type::FLOAT:
1614       type = GGANDIVA_TYPE_FLOAT_LITERAL_NODE;
1615       break;
1616     case arrow::Type::type::DOUBLE:
1617       type = GGANDIVA_TYPE_DOUBLE_LITERAL_NODE;
1618       break;
1619     case arrow::Type::type::STRING:
1620       type = GGANDIVA_TYPE_STRING_LITERAL_NODE;
1621       break;
1622     case arrow::Type::type::BINARY:
1623       type = GGANDIVA_TYPE_BINARY_LITERAL_NODE;
1624       break;
1625     default:
1626       type = GGANDIVA_TYPE_LITERAL_NODE;
1627       break;
1628     }
1629 
1630     if (return_type) {
1631       literal_node =
1632         GGANDIVA_LITERAL_NODE(g_object_new(type,
1633                                            "node", gandiva_node,
1634                                            "return-type", return_type,
1635                                            NULL));
1636     } else {
1637       return_type = garrow_data_type_new_raw(&arrow_return_type);
1638       literal_node =
1639         GGANDIVA_LITERAL_NODE(g_object_new(type,
1640                                            "node", gandiva_node,
1641                                            "return-type", return_type,
1642                                            NULL));
1643       g_object_unref(return_type);
1644     }
1645   }
1646 
1647   return literal_node;
1648 }
1649 
1650 GGandivaIfNode *
ggandiva_if_node_new_raw(std::shared_ptr<gandiva::Node> * gandiva_node,GGandivaNode * condition_node,GGandivaNode * then_node,GGandivaNode * else_node,GArrowDataType * return_type)1651 ggandiva_if_node_new_raw(std::shared_ptr<gandiva::Node> *gandiva_node,
1652                          GGandivaNode *condition_node,
1653                          GGandivaNode *then_node,
1654                          GGandivaNode *else_node,
1655                          GArrowDataType *return_type)
1656 {
1657   auto if_node = g_object_new(GGANDIVA_TYPE_IF_NODE,
1658                               "node", gandiva_node,
1659                               "condition-node", condition_node,
1660                               "then-node", then_node,
1661                               "else-node", else_node,
1662                               "return-type", return_type,
1663                               NULL);
1664   return GGANDIVA_IF_NODE(if_node);
1665 }
1666 
1667 GGandivaBooleanNode *
ggandiva_boolean_node_new_raw(std::shared_ptr<gandiva::Node> * gandiva_node,GList * children)1668 ggandiva_boolean_node_new_raw(std::shared_ptr<gandiva::Node> *gandiva_node,
1669                               GList *children)
1670 {
1671   auto gandiva_boolean_node =
1672     std::static_pointer_cast<gandiva::BooleanNode>(*gandiva_node);
1673 
1674   GType type;
1675   if (gandiva_boolean_node->expr_type() == gandiva::BooleanNode::AND) {
1676     type = GGANDIVA_TYPE_AND_NODE;
1677   } else {
1678     type = GGANDIVA_TYPE_OR_NODE;
1679   }
1680   auto boolean_node = g_object_new(type,
1681                                    "node", gandiva_node,
1682                                    NULL);
1683   auto priv = GGANDIVA_BOOLEAN_NODE_GET_PRIVATE(boolean_node);
1684   priv->children = g_list_copy_deep(children,
1685                                     reinterpret_cast<GCopyFunc>(g_object_ref),
1686                                     NULL);
1687   return GGANDIVA_BOOLEAN_NODE(boolean_node);
1688 }
1689