You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ko...@apache.org on 2018/12/19 02:40:10 UTC

[arrow] branch master updated: ARROW-4051: [Gandiva] [GLib] Add support for null literal

This is an automated email from the ASF dual-hosted git repository.

kou pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/master by this push:
     new 944b9e3  ARROW-4051: [Gandiva] [GLib] Add support for null literal
944b9e3 is described below

commit 944b9e319a5f208c0fc45953d1f10972b1433020
Author: Yosuke Shiro <yo...@gmail.com>
AuthorDate: Wed Dec 19 11:39:09 2018 +0900

    ARROW-4051: [Gandiva] [GLib] Add support for null literal
    
    - Add `#GGandivaNullLiteralNode`.
    - Remove `return_type` property in `#GGandivaFunctionNode` to use `ggandiva_node_get_return_type()`.
    
    Author: Yosuke Shiro <yo...@gmail.com>
    Author: Kouhei Sutou <ko...@clear-code.com>
    
    Closes #3197 from shiro615/glib-support-null-literal-node and squashes the following commits:
    
    4f0a39f7 <Kouhei Sutou> Fix a typo
    e93cd085 <Kouhei Sutou> Simplify
    be30df17 <Kouhei Sutou> Add tests for return-type of literal nodes
    8b3244e7 <Kouhei Sutou> Use data type from GArrowField as return type
    fcc0d8f8 <Kouhei Sutou> Raise error for invalid input
    41aada5e <Yosuke Shiro> Fix variable names
    415df817 <Yosuke Shiro> Add return-type property in ggandiva_field_node_new_raw()
    c337f122 <Yosuke Shiro> Call g_object_unref(data_type) to prevent a memory leak
    64cef1d8 <Yosuke Shiro> Use the given return_type to create GGandivaNullLiteralNode
    b17f5e25 <Yosuke Shiro> Reuse return-type property instead of defining ggandiva_node_get_return_type()
    3e25b0d5 <Yosuke Shiro> Refactor null check
    0ac03b4d <Yosuke Shiro> Add missing null check
    285f64b8 <Yosuke Shiro> Fix orders of class
    49d1044a <Yosuke Shiro> Remove return_type property for using ggandiva_node_get_return_type()
    f78881cf <Yosuke Shiro> Add ggandiva_node_get_return_type()
    5896f0bb <Yosuke Shiro>  Add GGandivaNullLiteralNode
---
 c_glib/gandiva-glib/node.cpp                       | 292 +++++++++++++++------
 c_glib/gandiva-glib/node.h                         |  17 ++
 c_glib/gandiva-glib/node.hpp                       |   3 +-
 c_glib/test/gandiva/test-binary-literal-node.rb    |  27 +-
 c_glib/test/gandiva/test-boolean-literal-node.rb   |  10 +-
 c_glib/test/gandiva/test-double-literal-node.rb    |  10 +-
 c_glib/test/gandiva/test-field-node.rb             |  10 +-
 c_glib/test/gandiva/test-float-literal-node.rb     |  14 +-
 c_glib/test/gandiva/test-int16-literal-node.rb     |  10 +-
 c_glib/test/gandiva/test-int32-literal-node.rb     |  10 +-
 c_glib/test/gandiva/test-int64-literal-node.rb     |  10 +-
 c_glib/test/gandiva/test-int8-literal-node.rb      |  10 +-
 ...t-literal-node.rb => test-null-literal-node.rb} |  20 +-
 c_glib/test/gandiva/test-string-literal-node.rb    |  10 +-
 c_glib/test/gandiva/test-uint16-literal-node.rb    |  10 +-
 c_glib/test/gandiva/test-uint32-literal-node.rb    |  10 +-
 c_glib/test/gandiva/test-uint64-literal-node.rb    |  10 +-
 c_glib/test/gandiva/test-uint8-literal-node.rb     |  10 +-
 18 files changed, 346 insertions(+), 147 deletions(-)

diff --git a/c_glib/gandiva-glib/node.cpp b/c_glib/gandiva-glib/node.cpp
index cdb9724..7098365 100644
--- a/c_glib/gandiva-glib/node.cpp
+++ b/c_glib/gandiva-glib/node.cpp
@@ -22,6 +22,7 @@
 #endif
 
 #include <arrow-glib/data-type.hpp>
+#include <arrow-glib/error.hpp>
 #include <arrow-glib/field.hpp>
 
 #include <gandiva-glib/node.hpp>
@@ -52,6 +53,9 @@ G_BEGIN_DECLS
  * #GGandivaLiteralNode is a base class for a node in the expression tree,
  * representing a literal.
  *
+ * #GGandivaNullLiteralNode is a class for a node in the expression tree,
+ * representing a null literal.
+ *
  * #GGandivaBooleanLiteralNode is a class for a node in the expression tree,
  * representing a boolean literal.
  *
@@ -96,10 +100,12 @@ G_BEGIN_DECLS
 
 typedef struct GGandivaNodePrivate_ {
   std::shared_ptr<gandiva::Node> node;
+  GArrowDataType *return_type;
 } GGandivaNodePrivate;
 
 enum {
-  PROP_NODE = 1
+  PROP_NODE = 1,
+  PROP_RETURN_TYPE
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE(GGandivaNode,
@@ -112,6 +118,19 @@ G_DEFINE_TYPE_WITH_PRIVATE(GGandivaNode,
       GGANDIVA_NODE(object)))
 
 static void
+ggandiva_node_dispose(GObject *object)
+{
+  auto priv = GGANDIVA_NODE_GET_PRIVATE(object);
+
+  if (priv->return_type) {
+    g_object_unref(priv->return_type);
+    priv->return_type = nullptr;
+  }
+
+  G_OBJECT_CLASS(ggandiva_node_parent_class)->dispose(object);
+}
+
+static void
 ggandiva_node_finalize(GObject *object)
 {
   auto priv = GGANDIVA_NODE_GET_PRIVATE(object);
@@ -134,6 +153,27 @@ ggandiva_node_set_property(GObject *object,
     priv->node =
       *static_cast<std::shared_ptr<gandiva::Node> *>(g_value_get_pointer(value));
     break;
+  case PROP_RETURN_TYPE:
+    priv->return_type = GARROW_DATA_TYPE(g_value_dup_object(value));
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
+}
+
+static void
+ggandiva_node_get_property(GObject *object,
+                           guint prop_id,
+                           GValue *value,
+                           GParamSpec *pspec)
+{
+  auto priv = GGANDIVA_NODE_GET_PRIVATE(object);
+
+  switch (prop_id) {
+  case PROP_RETURN_TYPE:
+    g_value_set_object(value, priv->return_type);
+    break;
   default:
     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
     break;
@@ -148,19 +188,28 @@ ggandiva_node_init(GGandivaNode *object)
 static void
 ggandiva_node_class_init(GGandivaNodeClass *klass)
 {
-  GParamSpec *spec;
-
   auto gobject_class = G_OBJECT_CLASS(klass);
 
+  gobject_class->dispose      = ggandiva_node_dispose;
   gobject_class->finalize     = ggandiva_node_finalize;
   gobject_class->set_property = ggandiva_node_set_property;
+  gobject_class->get_property = ggandiva_node_get_property;
 
+  GParamSpec *spec;
   spec = g_param_spec_pointer("node",
                               "Node",
                               "The raw std::shared<gandiva::Node> *",
                               static_cast<GParamFlags>(G_PARAM_WRITABLE |
                                                        G_PARAM_CONSTRUCT_ONLY));
   g_object_class_install_property(gobject_class, PROP_NODE, spec);
+
+  spec = g_param_spec_object("return-type",
+                             "Return type",
+                             "The return type",
+                             GARROW_TYPE_DATA_TYPE,
+                             static_cast<GParamFlags>(G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_RETURN_TYPE, spec);
 }
 
 
@@ -274,12 +323,10 @@ ggandiva_field_node_new(GArrowField *field)
 typedef struct GGandivaFunctionNodePrivate_ {
   gchar *name;
   GList *parameters;
-  GArrowDataType *return_type;
 } GGandivaFunctionNodePrivate;
 
 enum {
-  PROP_NAME = 1,
-  PROP_RETURN_TYPE
+  PROP_NAME = 1
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE(GGandivaFunctionNode,
@@ -305,11 +352,6 @@ ggandiva_function_node_dispose(GObject *object)
     priv->parameters = nullptr;
   }
 
-  if (priv->return_type) {
-    g_object_unref(priv->return_type);
-    priv->return_type = nullptr;
-  }
-
   G_OBJECT_CLASS(ggandiva_function_node_parent_class)->dispose(object);
 }
 
@@ -335,9 +377,6 @@ ggandiva_function_node_set_property(GObject *object,
   case PROP_NAME:
     priv->name = g_value_dup_string(value);
     break;
-  case PROP_RETURN_TYPE:
-    priv->return_type = GARROW_DATA_TYPE(g_value_dup_object(value));
-    break;
   default:
     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
     break;
@@ -356,9 +395,6 @@ ggandiva_function_node_get_property(GObject *object,
   case PROP_NAME:
     g_value_set_string(value, priv->name);
     break;
-  case PROP_RETURN_TYPE:
-    g_value_set_object(value, priv->return_type);
-    break;
   default:
     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
     break;
@@ -390,14 +426,6 @@ ggandiva_function_node_class_init(GGandivaFunctionNodeClass *klass)
                              static_cast<GParamFlags>(G_PARAM_READWRITE |
                                                       G_PARAM_CONSTRUCT_ONLY));
   g_object_class_install_property(gobject_class, PROP_NAME, spec);
-
-  spec = g_param_spec_object("return-type",
-                             "Return type",
-                             "The return type of the function",
-                             GARROW_TYPE_DATA_TYPE,
-                             static_cast<GParamFlags>(G_PARAM_READWRITE |
-                                                      G_PARAM_CONSTRUCT_ONLY));
-  g_object_class_install_property(gobject_class, PROP_RETURN_TYPE, spec);
 }
 
 /**
@@ -462,6 +490,50 @@ ggandiva_literal_node_class_init(GGandivaLiteralNodeClass *klass)
 }
 
 
+G_DEFINE_TYPE(GGandivaNullLiteralNode,
+              ggandiva_null_literal_node,
+              GGANDIVA_TYPE_LITERAL_NODE)
+
+static void
+ggandiva_null_literal_node_init(GGandivaNullLiteralNode *null_literal_node)
+{
+}
+
+static void
+ggandiva_null_literal_node_class_init(GGandivaNullLiteralNodeClass *klass)
+{
+}
+
+/**
+ * ggandiva_null_literal_node_new:
+ * @return_type: A #GArrowDataType.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (nullable): A newly created #GGandivaNullLiteralNode for
+ *   the type or %NULL on error.
+ *
+ * Since: 0.12.0
+ */
+GGandivaNullLiteralNode *
+ggandiva_null_literal_node_new(GArrowDataType *return_type,
+                               GError **error)
+{
+  auto arrow_return_type = garrow_data_type_get_raw(return_type);
+  auto gandiva_node = gandiva::TreeExprBuilder::MakeNull(arrow_return_type);
+  if (!gandiva_node) {
+    g_set_error(error,
+                GARROW_ERROR,
+                GARROW_ERROR_INVALID,
+                "[gandiva][null-literal-node][new] "
+                "failed to create: <%s>",
+                arrow_return_type->ToString().c_str());
+    return NULL;
+  }
+  return GGANDIVA_NULL_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
+                                                                  return_type));
+}
+
+
 G_DEFINE_TYPE(GGandivaBooleanLiteralNode,
               ggandiva_boolean_literal_node,
               GGANDIVA_TYPE_LITERAL_NODE)
@@ -488,7 +560,8 @@ GGandivaBooleanLiteralNode *
 ggandiva_boolean_literal_node_new(gboolean value)
 {
   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(static_cast<bool>(value));
-  return GGANDIVA_BOOLEAN_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node));
+  return GGANDIVA_BOOLEAN_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
+                                                                     NULL));
 }
 
 /**
@@ -533,7 +606,8 @@ GGandivaInt8LiteralNode *
 ggandiva_int8_literal_node_new(gint8 value)
 {
   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(value);
-  return GGANDIVA_INT8_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node));
+  return GGANDIVA_INT8_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
+                                                                  NULL));
 }
 
 /**
@@ -577,7 +651,8 @@ GGandivaUInt8LiteralNode *
 ggandiva_uint8_literal_node_new(guint8 value)
 {
   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(value);
-  return GGANDIVA_UINT8_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node));
+  return GGANDIVA_UINT8_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
+                                                                   NULL));
 }
 
 /**
@@ -621,7 +696,8 @@ GGandivaInt16LiteralNode *
 ggandiva_int16_literal_node_new(gint16 value)
 {
   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(value);
-  return GGANDIVA_INT16_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node));
+  return GGANDIVA_INT16_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
+                                                                   NULL));
 }
 
 /**
@@ -665,7 +741,8 @@ GGandivaUInt16LiteralNode *
 ggandiva_uint16_literal_node_new(guint16 value)
 {
   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(value);
-  return GGANDIVA_UINT16_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node));
+  return GGANDIVA_UINT16_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
+                                                                    NULL));
 }
 
 /**
@@ -709,7 +786,8 @@ GGandivaInt32LiteralNode *
 ggandiva_int32_literal_node_new(gint32 value)
 {
   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(value);
-  return GGANDIVA_INT32_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node));
+  return GGANDIVA_INT32_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
+                                                                   NULL));
 }
 
 /**
@@ -753,7 +831,8 @@ GGandivaUInt32LiteralNode *
 ggandiva_uint32_literal_node_new(guint32 value)
 {
   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(value);
-  return GGANDIVA_UINT32_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node));
+  return GGANDIVA_UINT32_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
+                                                                    NULL));
 }
 
 /**
@@ -797,7 +876,8 @@ GGandivaInt64LiteralNode *
 ggandiva_int64_literal_node_new(gint64 value)
 {
   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(value);
-  return GGANDIVA_INT64_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node));
+  return GGANDIVA_INT64_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
+                                                                   NULL));
 }
 
 /**
@@ -841,7 +921,8 @@ GGandivaUInt64LiteralNode *
 ggandiva_uint64_literal_node_new(guint64 value)
 {
   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(value);
-  return GGANDIVA_UINT64_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node));
+  return GGANDIVA_UINT64_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
+                                                                    NULL));
 }
 
 /**
@@ -885,7 +966,8 @@ GGandivaFloatLiteralNode *
 ggandiva_float_literal_node_new(gfloat value)
 {
   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(value);
-  return GGANDIVA_FLOAT_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node));
+  return GGANDIVA_FLOAT_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
+                                                                   NULL));
 }
 
 /**
@@ -929,7 +1011,8 @@ GGandivaDoubleLiteralNode *
 ggandiva_double_literal_node_new(gdouble value)
 {
   auto gandiva_node = gandiva::TreeExprBuilder::MakeLiteral(value);
-  return GGANDIVA_DOUBLE_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node));
+  return GGANDIVA_DOUBLE_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
+                                                                    NULL));
 }
 
 /**
@@ -1002,7 +1085,8 @@ ggandiva_binary_literal_node_new(const guint8 *value,
   auto gandiva_node =
     gandiva::TreeExprBuilder::MakeBinaryLiteral(std::string(reinterpret_cast<const char *>(value),
                                                             size));
-  return GGANDIVA_BINARY_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node));
+  return GGANDIVA_BINARY_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
+                                                                    NULL));
 }
 
 /**
@@ -1022,7 +1106,8 @@ ggandiva_binary_literal_node_new_bytes(GBytes *value)
     gandiva::TreeExprBuilder::MakeBinaryLiteral(
       std::string(reinterpret_cast<const char *>(raw_value),
                   value_size));
-  auto literal_node = ggandiva_literal_node_new_raw(&gandiva_node);
+  auto literal_node = ggandiva_literal_node_new_raw(&gandiva_node,
+                                                    NULL);
   auto priv = GGANDIVA_BINARY_LITERAL_NODE_GET_PRIVATE(literal_node);
   priv->value = value;
   g_bytes_ref(priv->value);
@@ -1076,7 +1161,8 @@ GGandivaStringLiteralNode *
 ggandiva_string_literal_node_new(const gchar *value)
 {
   auto gandiva_node = gandiva::TreeExprBuilder::MakeStringLiteral(value);
-  return GGANDIVA_STRING_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node));
+  return GGANDIVA_STRING_LITERAL_NODE(ggandiva_literal_node_new_raw(&gandiva_node,
+                                                                    NULL));
 }
 
 /**
@@ -1107,10 +1193,14 @@ GGandivaFieldNode *
 ggandiva_field_node_new_raw(std::shared_ptr<gandiva::Node> *gandiva_node,
                             GArrowField *field)
 {
+  auto arrow_return_type = (*gandiva_node)->return_type();
+  auto return_type = garrow_field_get_data_type(field);
   auto field_node = g_object_new(GGANDIVA_TYPE_FIELD_NODE,
                                  "node", gandiva_node,
                                  "field", field,
+                                 "return-type", return_type,
                                  NULL);
+  g_object_unref(return_type);
   return GGANDIVA_FIELD_NODE(field_node);
 }
 
@@ -1135,56 +1225,84 @@ ggandiva_function_node_new_raw(std::shared_ptr<gandiva::Node> *gandiva_node,
 }
 
 GGandivaLiteralNode *
-ggandiva_literal_node_new_raw(std::shared_ptr<gandiva::Node> *gandiva_node)
+ggandiva_literal_node_new_raw(std::shared_ptr<gandiva::Node> *gandiva_node,
+                              GArrowDataType *return_type)
 {
-  GType type;
+  auto gandiva_literal_node =
+    std::static_pointer_cast<gandiva::LiteralNode>(*gandiva_node);
+
+  GGandivaLiteralNode *literal_node;
+  if (gandiva_literal_node->is_null()) {
+    literal_node =
+      GGANDIVA_LITERAL_NODE(g_object_new(GGANDIVA_TYPE_NULL_LITERAL_NODE,
+                                         "node", gandiva_node,
+                                         "return-type", return_type,
+                                         NULL));
+  } else {
+    GType type;
+
+    auto arrow_return_type = gandiva_literal_node->return_type();
+    switch (arrow_return_type->id()) {
+    case arrow::Type::BOOL:
+      type = GGANDIVA_TYPE_BOOLEAN_LITERAL_NODE;
+      break;
+    case arrow::Type::type::UINT8:
+      type = GGANDIVA_TYPE_UINT8_LITERAL_NODE;
+      break;
+    case arrow::Type::type::UINT16:
+      type = GGANDIVA_TYPE_UINT16_LITERAL_NODE;
+      break;
+    case arrow::Type::type::UINT32:
+      type = GGANDIVA_TYPE_UINT32_LITERAL_NODE;
+      break;
+    case arrow::Type::type::UINT64:
+      type = GGANDIVA_TYPE_UINT64_LITERAL_NODE;
+      break;
+    case arrow::Type::type::INT8:
+      type = GGANDIVA_TYPE_INT8_LITERAL_NODE;
+      break;
+    case arrow::Type::type::INT16:
+      type = GGANDIVA_TYPE_INT16_LITERAL_NODE;
+      break;
+    case arrow::Type::type::INT32:
+      type = GGANDIVA_TYPE_INT32_LITERAL_NODE;
+      break;
+    case arrow::Type::type::INT64:
+      type = GGANDIVA_TYPE_INT64_LITERAL_NODE;
+      break;
+    case arrow::Type::type::FLOAT:
+      type = GGANDIVA_TYPE_FLOAT_LITERAL_NODE;
+      break;
+    case arrow::Type::type::DOUBLE:
+      type = GGANDIVA_TYPE_DOUBLE_LITERAL_NODE;
+      break;
+    case arrow::Type::type::STRING:
+      type = GGANDIVA_TYPE_STRING_LITERAL_NODE;
+      break;
+    case arrow::Type::type::BINARY:
+      type = GGANDIVA_TYPE_BINARY_LITERAL_NODE;
+      break;
+    default:
+      type = GGANDIVA_TYPE_LITERAL_NODE;
+      break;
+    }
 
-  switch ((*gandiva_node)->return_type()->id()) {
-  case arrow::Type::BOOL:
-    type = GGANDIVA_TYPE_BOOLEAN_LITERAL_NODE;
-    break;
-  case arrow::Type::type::UINT8:
-    type = GGANDIVA_TYPE_UINT8_LITERAL_NODE;
-    break;
-  case arrow::Type::type::UINT16:
-    type = GGANDIVA_TYPE_UINT16_LITERAL_NODE;
-    break;
-  case arrow::Type::type::UINT32:
-    type = GGANDIVA_TYPE_UINT32_LITERAL_NODE;
-    break;
-  case arrow::Type::type::UINT64:
-    type = GGANDIVA_TYPE_UINT64_LITERAL_NODE;
-    break;
-  case arrow::Type::type::INT8:
-    type = GGANDIVA_TYPE_INT8_LITERAL_NODE;
-    break;
-  case arrow::Type::type::INT16:
-    type = GGANDIVA_TYPE_INT16_LITERAL_NODE;
-    break;
-  case arrow::Type::type::INT32:
-    type = GGANDIVA_TYPE_INT32_LITERAL_NODE;
-    break;
-  case arrow::Type::type::INT64:
-    type = GGANDIVA_TYPE_INT64_LITERAL_NODE;
-    break;
-  case arrow::Type::type::FLOAT:
-    type = GGANDIVA_TYPE_FLOAT_LITERAL_NODE;
-    break;
-  case arrow::Type::type::DOUBLE:
-    type = GGANDIVA_TYPE_DOUBLE_LITERAL_NODE;
-    break;
-  case arrow::Type::type::STRING:
-    type = GGANDIVA_TYPE_STRING_LITERAL_NODE;
-    break;
-  case arrow::Type::type::BINARY:
-    type = GGANDIVA_TYPE_BINARY_LITERAL_NODE;
-    break;
-  default:
-    type = GGANDIVA_TYPE_LITERAL_NODE;
-    break;
+    if (return_type) {
+      literal_node =
+        GGANDIVA_LITERAL_NODE(g_object_new(type,
+                                           "node", gandiva_node,
+                                           "return-type", return_type,
+                                           NULL));
+    } else {
+      return_type = garrow_data_type_new_raw(&arrow_return_type);
+      literal_node =
+        GGANDIVA_LITERAL_NODE(g_object_new(type,
+                                           "node", gandiva_node,
+                                           "return-type", return_type,
+                                           NULL));
+      g_object_unref(return_type);
+    }
   }
-  auto literal_node = GGANDIVA_LITERAL_NODE(g_object_new(type,
-                                                         "node", gandiva_node,
-                                                         NULL));
+
   return literal_node;
 }
diff --git a/c_glib/gandiva-glib/node.h b/c_glib/gandiva-glib/node.h
index 183003f..d9e67e2 100644
--- a/c_glib/gandiva-glib/node.h
+++ b/c_glib/gandiva-glib/node.h
@@ -35,6 +35,7 @@ struct _GGandivaNodeClass
   GObjectClass parent_class;
 };
 
+
 #define GGANDIVA_TYPE_FIELD_NODE (ggandiva_field_node_get_type())
 G_DECLARE_DERIVABLE_TYPE(GGandivaFieldNode,
                          ggandiva_field_node,
@@ -80,6 +81,22 @@ struct _GGandivaLiteralNodeClass
 };
 
 
+#define GGANDIVA_TYPE_NULL_LITERAL_NODE (ggandiva_null_literal_node_get_type())
+G_DECLARE_DERIVABLE_TYPE(GGandivaNullLiteralNode,
+                         ggandiva_null_literal_node,
+                         GGANDIVA,
+                         NULL_LITERAL_NODE,
+                         GGandivaLiteralNode)
+struct _GGandivaNullLiteralNodeClass
+{
+  GGandivaLiteralNodeClass parent_class;
+};
+
+GGandivaNullLiteralNode *
+ggandiva_null_literal_node_new(GArrowDataType *return_type,
+                               GError **error);
+
+
 #define GGANDIVA_TYPE_BOOLEAN_LITERAL_NODE (ggandiva_boolean_literal_node_get_type())
 G_DECLARE_DERIVABLE_TYPE(GGandivaBooleanLiteralNode,
                          ggandiva_boolean_literal_node,
diff --git a/c_glib/gandiva-glib/node.hpp b/c_glib/gandiva-glib/node.hpp
index 7ff1360..40f9d1b 100644
--- a/c_glib/gandiva-glib/node.hpp
+++ b/c_glib/gandiva-glib/node.hpp
@@ -36,4 +36,5 @@ ggandiva_function_node_new_raw(std::shared_ptr<gandiva::Node> *gandiva_node,
                                GList *parameters,
                                GArrowDataType *return_type);
 GGandivaLiteralNode *
-ggandiva_literal_node_new_raw(std::shared_ptr<gandiva::Node> *gandiva_node);
+ggandiva_literal_node_new_raw(std::shared_ptr<gandiva::Node> *gandiva_node,
+                              GArrowDataType *return_type);
diff --git a/c_glib/test/gandiva/test-binary-literal-node.rb b/c_glib/test/gandiva/test-binary-literal-node.rb
index 93a54a3..fddf748 100644
--- a/c_glib/test/gandiva/test-binary-literal-node.rb
+++ b/c_glib/test/gandiva/test-binary-literal-node.rb
@@ -21,14 +21,27 @@ class TestGandivaBinaryLiteralNode < Test::Unit::TestCase
     @value = "\x00\x01\x02\x03\x04"
   end
 
-  def test_new
-    literal_node = Gandiva::BinaryLiteralNode.new(@value)
-    assert_equal(@value, literal_node.value.to_s)
+  sub_test_case(".new") do
+    def test_string
+      node = Gandiva::BinaryLiteralNode.new(@value)
+      assert_equal(@value, node.value.to_s)
+    end
+
+    def test_bytes
+      bytes_value = GLib::Bytes.new(@value)
+      node = Gandiva::BinaryLiteralNode.new(bytes_value)
+      assert_equal(@value, node.value.to_s)
+    end
   end
 
-  def test_new_bytes
-    bytes_value = GLib::Bytes.new(@value)
-    literal_node = Gandiva::BinaryLiteralNode.new(bytes_value)
-    assert_equal(@value, literal_node.value.to_s)
+  sub_test_case("instance methods") do
+    def setup
+      super
+      @node = Gandiva::BinaryLiteralNode.new(@value)
+    end
+
+    def test_return_type
+      assert_equal(Arrow::BinaryDataType.new, @node.return_type)
+    end
   end
 end
diff --git a/c_glib/test/gandiva/test-boolean-literal-node.rb b/c_glib/test/gandiva/test-boolean-literal-node.rb
index 3d1f10c..6e18a76 100644
--- a/c_glib/test/gandiva/test-boolean-literal-node.rb
+++ b/c_glib/test/gandiva/test-boolean-literal-node.rb
@@ -18,11 +18,15 @@
 class TestGandivaBooleanLiteralNode < Test::Unit::TestCase
   def setup
     omit("Gandiva is required") unless defined?(::Gandiva)
+    @value = true
+    @node = Gandiva::BooleanLiteralNode.new(@value)
   end
 
   def test_value
-    value = true
-    literal_node = Gandiva::BooleanLiteralNode.new(value)
-    assert_equal(value, literal_node.value?)
+    assert_equal(@value, @node.value?)
+  end
+
+  def test_return_type
+    assert_equal(Arrow::BooleanDataType.new, @node.return_type)
   end
 end
diff --git a/c_glib/test/gandiva/test-double-literal-node.rb b/c_glib/test/gandiva/test-double-literal-node.rb
index fd4bd08..27cc3ae 100644
--- a/c_glib/test/gandiva/test-double-literal-node.rb
+++ b/c_glib/test/gandiva/test-double-literal-node.rb
@@ -18,11 +18,15 @@
 class TestGandivaDoubleLiteralNode < Test::Unit::TestCase
   def setup
     omit("Gandiva is required") unless defined?(::Gandiva)
+    @value = 1.5
+    @node = Gandiva::DoubleLiteralNode.new(@value)
   end
 
   def test_value
-    value = 1.5
-    literal_node = Gandiva::DoubleLiteralNode.new(value)
-    assert_equal(value, literal_node.value)
+    assert_equal(@value, @node.value)
+  end
+
+  def test_return_type
+    assert_equal(Arrow::DoubleDataType.new, @node.return_type)
   end
 end
diff --git a/c_glib/test/gandiva/test-field-node.rb b/c_glib/test/gandiva/test-field-node.rb
index c5bfe6c..51db285 100644
--- a/c_glib/test/gandiva/test-field-node.rb
+++ b/c_glib/test/gandiva/test-field-node.rb
@@ -18,11 +18,15 @@
 class TestGandivaFieldNode < Test::Unit::TestCase
   def setup
     omit("Gandiva is required") unless defined?(::Gandiva)
+    @field = Arrow::Field.new("valid", Arrow::BooleanDataType.new)
+    @node = Gandiva::FieldNode.new(@field)
   end
 
   def test_field
-    field = Arrow::Field.new("valid", Arrow::BooleanDataType.new)
-    field_node = Gandiva::FieldNode.new(field)
-    assert_equal(field, field_node.field)
+    assert_equal(@field, @node.field)
+  end
+
+  def test_return_type
+    assert_equal(@field.data_type, @node.return_type)
   end
 end
diff --git a/c_glib/test/gandiva/test-float-literal-node.rb b/c_glib/test/gandiva/test-float-literal-node.rb
index 202ec38..4a49eb3 100644
--- a/c_glib/test/gandiva/test-float-literal-node.rb
+++ b/c_glib/test/gandiva/test-float-literal-node.rb
@@ -18,17 +18,15 @@
 class TestGandivaFloatLiteralNode < Test::Unit::TestCase
   def setup
     omit("Gandiva is required") unless defined?(::Gandiva)
+    @value = 1.5
+    @node = Gandiva::FloatLiteralNode.new(@value)
   end
 
-  def test_new
-    assert_nothing_raised do
-      Gandiva::FloatLiteralNode.new(1.5)
-    end
+  def test_value
+    assert_equal(@value, @node.value)
   end
 
-  def test_value
-    value = 1.5
-    literal_node = Gandiva::FloatLiteralNode.new(value)
-    assert_equal(value, literal_node.value)
+  def test_return_type
+    assert_equal(Arrow::FloatDataType.new, @node.return_type)
   end
 end
diff --git a/c_glib/test/gandiva/test-int16-literal-node.rb b/c_glib/test/gandiva/test-int16-literal-node.rb
index 9b5bb68..f8e6b26 100644
--- a/c_glib/test/gandiva/test-int16-literal-node.rb
+++ b/c_glib/test/gandiva/test-int16-literal-node.rb
@@ -18,11 +18,15 @@
 class TestGandivaInt16LiteralNode < Test::Unit::TestCase
   def setup
     omit("Gandiva is required") unless defined?(::Gandiva)
+    @value = -(2 ** 15)
+    @node = Gandiva::Int16LiteralNode.new(@value)
   end
 
   def test_value
-    value = -3
-    literal_node = Gandiva::Int16LiteralNode.new(value)
-    assert_equal(value, literal_node.value)
+    assert_equal(@value, @node.value)
+  end
+
+  def test_return_type
+    assert_equal(Arrow::Int16DataType.new, @node.return_type)
   end
 end
diff --git a/c_glib/test/gandiva/test-int32-literal-node.rb b/c_glib/test/gandiva/test-int32-literal-node.rb
index 9c94cde..3d1bf58 100644
--- a/c_glib/test/gandiva/test-int32-literal-node.rb
+++ b/c_glib/test/gandiva/test-int32-literal-node.rb
@@ -18,11 +18,15 @@
 class TestGandivaInt32LiteralNode < Test::Unit::TestCase
   def setup
     omit("Gandiva is required") unless defined?(::Gandiva)
+    @value = -(2 ** 31)
+    @node = Gandiva::Int32LiteralNode.new(@value)
   end
 
   def test_value
-    value = -3
-    literal_node = Gandiva::Int32LiteralNode.new(value)
-    assert_equal(value, literal_node.value)
+    assert_equal(@value, @node.value)
+  end
+
+  def test_return_type
+    assert_equal(Arrow::Int32DataType.new, @node.return_type)
   end
 end
diff --git a/c_glib/test/gandiva/test-int64-literal-node.rb b/c_glib/test/gandiva/test-int64-literal-node.rb
index e1b4b91..b2ca3bf 100644
--- a/c_glib/test/gandiva/test-int64-literal-node.rb
+++ b/c_glib/test/gandiva/test-int64-literal-node.rb
@@ -18,11 +18,15 @@
 class TestGandivaInt64LiteralNode < Test::Unit::TestCase
   def setup
     omit("Gandiva is required") unless defined?(::Gandiva)
+    @value = -(2 ** 63)
+    @node = Gandiva::Int64LiteralNode.new(@value)
   end
 
   def test_value
-    value = -3
-    literal_node = Gandiva::Int64LiteralNode.new(value)
-    assert_equal(value, literal_node.value)
+    assert_equal(@value, @node.value)
+  end
+
+  def test_return_type
+    assert_equal(Arrow::Int64DataType.new, @node.return_type)
   end
 end
diff --git a/c_glib/test/gandiva/test-int8-literal-node.rb b/c_glib/test/gandiva/test-int8-literal-node.rb
index 30f11fc..8d917bd 100644
--- a/c_glib/test/gandiva/test-int8-literal-node.rb
+++ b/c_glib/test/gandiva/test-int8-literal-node.rb
@@ -18,11 +18,15 @@
 class TestGandivaInt8LiteralNode < Test::Unit::TestCase
   def setup
     omit("Gandiva is required") unless defined?(::Gandiva)
+    @value = -(2 ** 7)
+    @node = Gandiva::Int8LiteralNode.new(@value)
   end
 
   def test_value
-    value = -3
-    literal_node = Gandiva::Int8LiteralNode.new(value)
-    assert_equal(value, literal_node.value)
+    assert_equal(@value, @node.value)
+  end
+
+  def test_return_type
+    assert_equal(Arrow::Int8DataType.new, @node.return_type)
   end
 end
diff --git a/c_glib/test/gandiva/test-float-literal-node.rb b/c_glib/test/gandiva/test-null-literal-node.rb
similarity index 63%
copy from c_glib/test/gandiva/test-float-literal-node.rb
copy to c_glib/test/gandiva/test-null-literal-node.rb
index 202ec38..ae14f3c 100644
--- a/c_glib/test/gandiva/test-float-literal-node.rb
+++ b/c_glib/test/gandiva/test-null-literal-node.rb
@@ -15,20 +15,24 @@
 # specific language governing permissions and limitations
 # under the License.
 
-class TestGandivaFloatLiteralNode < Test::Unit::TestCase
+class TestGandivaNullLiteralNode < Test::Unit::TestCase
   def setup
     omit("Gandiva is required") unless defined?(::Gandiva)
   end
 
-  def test_new
-    assert_nothing_raised do
-      Gandiva::FloatLiteralNode.new(1.5)
+  def test_invalid_type
+    return_type = Arrow::NullDataType.new
+    message =
+      "[gandiva][null-literal-node][new] " +
+      "failed to create: <#{return_type}>"
+    assert_raise(Arrow::Error::Invalid.new(message)) do
+      Gandiva::NullLiteralNode.new(return_type)
     end
   end
 
-  def test_value
-    value = 1.5
-    literal_node = Gandiva::FloatLiteralNode.new(value)
-    assert_equal(value, literal_node.value)
+  def test_return_type
+    return_type = Arrow::BooleanDataType.new
+    literal_node = Gandiva::NullLiteralNode.new(return_type)
+    assert_equal(return_type, literal_node.return_type)
   end
 end
diff --git a/c_glib/test/gandiva/test-string-literal-node.rb b/c_glib/test/gandiva/test-string-literal-node.rb
index a231f61..8a397ab 100644
--- a/c_glib/test/gandiva/test-string-literal-node.rb
+++ b/c_glib/test/gandiva/test-string-literal-node.rb
@@ -18,11 +18,15 @@
 class TestGandivaStringLiteralNode < Test::Unit::TestCase
   def setup
     omit("Gandiva is required") unless defined?(::Gandiva)
+    @value = "Hello"
+    @node = Gandiva::StringLiteralNode.new(@value)
   end
 
   def test_value
-    value = "Hello"
-    literal_node = Gandiva::StringLiteralNode.new(value)
-    assert_equal(value, literal_node.value)
+    assert_equal(@value, @node.value)
+  end
+
+  def test_return_type
+    assert_equal(Arrow::StringDataType.new, @node.return_type)
   end
 end
diff --git a/c_glib/test/gandiva/test-uint16-literal-node.rb b/c_glib/test/gandiva/test-uint16-literal-node.rb
index e8bdd30..971da38 100644
--- a/c_glib/test/gandiva/test-uint16-literal-node.rb
+++ b/c_glib/test/gandiva/test-uint16-literal-node.rb
@@ -18,11 +18,15 @@
 class TestGandivaUInt16LiteralNode < Test::Unit::TestCase
   def setup
     omit("Gandiva is required") unless defined?(::Gandiva)
+    @value = 2 ** 16 - 1
+    @node = Gandiva::UInt16LiteralNode.new(@value)
   end
 
   def test_value
-    value = 3
-    literal_node = Gandiva::UInt16LiteralNode.new(value)
-    assert_equal(value, literal_node.value)
+    assert_equal(@value, @node.value)
+  end
+
+  def test_return_type
+    assert_equal(Arrow::UInt16DataType.new, @node.return_type)
   end
 end
diff --git a/c_glib/test/gandiva/test-uint32-literal-node.rb b/c_glib/test/gandiva/test-uint32-literal-node.rb
index 9d59957..8fcab7f 100644
--- a/c_glib/test/gandiva/test-uint32-literal-node.rb
+++ b/c_glib/test/gandiva/test-uint32-literal-node.rb
@@ -18,11 +18,15 @@
 class TestGandivaUInt32LiteralNode < Test::Unit::TestCase
   def setup
     omit("Gandiva is required") unless defined?(::Gandiva)
+    @value = 2 ** 32 - 1
+    @node = Gandiva::UInt32LiteralNode.new(@value)
   end
 
   def test_value
-    value = 3
-    literal_node = Gandiva::UInt32LiteralNode.new(value)
-    assert_equal(value, literal_node.value)
+    assert_equal(@value, @node.value)
+  end
+
+  def test_return_type
+    assert_equal(Arrow::UInt32DataType.new, @node.return_type)
   end
 end
diff --git a/c_glib/test/gandiva/test-uint64-literal-node.rb b/c_glib/test/gandiva/test-uint64-literal-node.rb
index 56c46db..d5afddc 100644
--- a/c_glib/test/gandiva/test-uint64-literal-node.rb
+++ b/c_glib/test/gandiva/test-uint64-literal-node.rb
@@ -18,11 +18,15 @@
 class TestGandivaUInt64LiteralNode < Test::Unit::TestCase
   def setup
     omit("Gandiva is required") unless defined?(::Gandiva)
+    @value = 3
+    @node = Gandiva::UInt64LiteralNode.new(@value)
   end
 
   def test_value
-    value = 3
-    literal_node = Gandiva::UInt64LiteralNode.new(value)
-    assert_equal(value, literal_node.value)
+    assert_equal(@value, @node.value)
+  end
+
+  def test_return_type
+    assert_equal(Arrow::UInt64DataType.new, @node.return_type)
   end
 end
diff --git a/c_glib/test/gandiva/test-uint8-literal-node.rb b/c_glib/test/gandiva/test-uint8-literal-node.rb
index 04f76cd..8ce91d5 100644
--- a/c_glib/test/gandiva/test-uint8-literal-node.rb
+++ b/c_glib/test/gandiva/test-uint8-literal-node.rb
@@ -18,11 +18,15 @@
 class TestGandivaUInt8LiteralNode < Test::Unit::TestCase
   def setup
     omit("Gandiva is required") unless defined?(::Gandiva)
+    @value = 2 ** 8 - 1
+    @node = Gandiva::UInt8LiteralNode.new(@value)
   end
 
   def test_value
-    value = 3
-    literal_node = Gandiva::UInt8LiteralNode.new(value)
-    assert_equal(value, literal_node.value)
+    assert_equal(@value, @node.value)
+  end
+
+  def test_return_type
+    assert_equal(Arrow::UInt8DataType.new, @node.return_type)
   end
 end