You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by we...@apache.org on 2020/04/06 00:06:19 UTC

[arrow] branch master updated: ARROW-8334: [C++] [Gandiva] Missing DATE32 in LLVM Types

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

wesm 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 6d92694  ARROW-8334: [C++] [Gandiva] Missing DATE32 in LLVM Types
6d92694 is described below

commit 6d92694d00aec08081ae1bfe06f0a265e141b1b7
Author: Dominik Durner <du...@zoho.com>
AuthorDate: Sun Apr 5 19:05:32 2020 -0500

    ARROW-8334: [C++] [Gandiva] Missing DATE32 in LLVM Types
    
    Closes #6835 from durner/date32
    
    Authored-by: Dominik Durner <du...@zoho.com>
    Signed-off-by: Wes McKinney <we...@apache.org>
---
 cpp/src/gandiva/function_registry_arithmetic.cc |  1 +
 cpp/src/gandiva/function_registry_common.h      |  3 +-
 cpp/src/gandiva/llvm_generator.cc               |  4 +++
 cpp/src/gandiva/llvm_types.cc                   |  1 +
 cpp/src/gandiva/precompiled/arithmetic_ops.cc   |  2 ++
 cpp/src/gandiva/precompiled/hash.cc             |  1 +
 cpp/src/gandiva/precompiled/time.cc             |  3 ++
 cpp/src/gandiva/precompiled/types.h             |  5 ++++
 cpp/src/gandiva/tests/date_time_test.cc         | 38 +++++++++++++++++++++++++
 cpp/src/gandiva/tree_expr_builder.cc            |  2 ++
 10 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/cpp/src/gandiva/function_registry_arithmetic.cc b/cpp/src/gandiva/function_registry_arithmetic.cc
index f098533..d24020f 100644
--- a/cpp/src/gandiva/function_registry_arithmetic.cc
+++ b/cpp/src/gandiva/function_registry_arithmetic.cc
@@ -61,6 +61,7 @@ std::vector<NativeFunction> GetArithmeticFunctionRegistry() {
                      "castDECIMALNullOnOverflow_decimal128"),
 
       UNARY_SAFE_NULL_IF_NULL(castDATE, {}, int64, date64),
+      UNARY_SAFE_NULL_IF_NULL(castDATE, {}, int32, date32),
 
       // add/sub/multiply/divide/mod
       BINARY_SYMMETRIC_FN(add, {}), BINARY_SYMMETRIC_FN(subtract, {}),
diff --git a/cpp/src/gandiva/function_registry_common.h b/cpp/src/gandiva/function_registry_common.h
index 442796d..3ed4fa9 100644
--- a/cpp/src/gandiva/function_registry_common.h
+++ b/cpp/src/gandiva/function_registry_common.h
@@ -34,6 +34,7 @@ namespace gandiva {
 
 using arrow::binary;
 using arrow::boolean;
+using arrow::date32;
 using arrow::date64;
 using arrow::day_time_interval;
 using arrow::float32;
@@ -205,7 +206,7 @@ typedef std::unordered_map<const FunctionSignature*, const NativeFunction*, KeyH
 // Iterate the inner macro over numeric and date/time types
 #define NUMERIC_DATE_TYPES(INNER, NAME, ALIASES)                         \
   NUMERIC_TYPES(INNER, NAME, ALIASES), DATE_TYPES(INNER, NAME, ALIASES), \
-      TIME_TYPES(INNER, NAME, ALIASES)
+      TIME_TYPES(INNER, NAME, ALIASES), INNER(NAME, ALIASES, date32)
 
 // Iterate the inner macro over all date types
 #define DATE_TYPES(INNER, NAME, ALIASES) \
diff --git a/cpp/src/gandiva/llvm_generator.cc b/cpp/src/gandiva/llvm_generator.cc
index 69403ed..b45c0f1 100644
--- a/cpp/src/gandiva/llvm_generator.cc
+++ b/cpp/src/gandiva/llvm_generator.cc
@@ -692,6 +692,10 @@ void LLVMGenerator::Visitor::Visit(const LiteralDex& dex) {
       break;
     }
 
+    case arrow::Type::DATE32:
+      value = types->i32_constant(arrow::util::get<int32_t>(dex.holder()));
+      break;
+
     case arrow::Type::DATE64:
       value = types->i64_constant(arrow::util::get<int64_t>(dex.holder()));
       break;
diff --git a/cpp/src/gandiva/llvm_types.cc b/cpp/src/gandiva/llvm_types.cc
index 008cde3..6496f03 100644
--- a/cpp/src/gandiva/llvm_types.cc
+++ b/cpp/src/gandiva/llvm_types.cc
@@ -34,6 +34,7 @@ LLVMTypes::LLVMTypes(llvm::LLVMContext& context) : context_(context) {
       {arrow::Type::type::UINT64, i64_type()},
       {arrow::Type::type::FLOAT, float_type()},
       {arrow::Type::type::DOUBLE, double_type()},
+      {arrow::Type::type::DATE32, i32_type()},
       {arrow::Type::type::DATE64, i64_type()},
       {arrow::Type::type::TIME32, i32_type()},
       {arrow::Type::type::TIME64, i64_type()},
diff --git a/cpp/src/gandiva/precompiled/arithmetic_ops.cc b/cpp/src/gandiva/precompiled/arithmetic_ops.cc
index ba97bd4..afeb2f9 100644
--- a/cpp/src/gandiva/precompiled/arithmetic_ops.cc
+++ b/cpp/src/gandiva/precompiled/arithmetic_ops.cc
@@ -36,6 +36,7 @@ extern "C" {
 // Expand inner macros for all date/time types.
 #define DATE_TYPES(INNER, NAME, OP) \
   INNER(NAME, date64, OP)           \
+  INNER(NAME, date32, OP)           \
   INNER(NAME, timestamp, OP)        \
   INNER(NAME, time32, OP)
 
@@ -139,6 +140,7 @@ NUMERIC_TYPES(VALIDITY_OP, isnumeric, +)
   INNER(float64)
 
 #define DATE_FUNCTION(INNER) \
+  INNER(date32)              \
   INNER(date64)              \
   INNER(timestamp)           \
   INNER(time32)
diff --git a/cpp/src/gandiva/precompiled/hash.cc b/cpp/src/gandiva/precompiled/hash.cc
index 1dc3708..0e431f1 100644
--- a/cpp/src/gandiva/precompiled/hash.cc
+++ b/cpp/src/gandiva/precompiled/hash.cc
@@ -169,6 +169,7 @@ FORCE_INLINE gdv_int32 hash32(double val, gdv_int32 seed) {
   INNER(NAME, float64)                       \
   INNER(NAME, boolean)                       \
   INNER(NAME, date64)                        \
+  INNER(NAME, date32)                        \
   INNER(NAME, time32)                        \
   INNER(NAME, timestamp)
 
diff --git a/cpp/src/gandiva/precompiled/time.cc b/cpp/src/gandiva/precompiled/time.cc
index 4a53197..d3e4484 100644
--- a/cpp/src/gandiva/precompiled/time.cc
+++ b/cpp/src/gandiva/precompiled/time.cc
@@ -37,6 +37,7 @@ extern "C" {
 
 // Expand inner macro for all date types.
 #define DATE_TYPES(INNER) \
+  INNER(date32)           \
   INNER(date64)           \
   INNER(timestamp)
 
@@ -453,6 +454,8 @@ DATE_TRUNC_FUNCTIONS(timestamp)
 
 FORCE_INLINE
 gdv_date64 castDATE_int64(gdv_int64 in) { return in; }
+FORCE_INLINE
+gdv_date32 castDATE_int32(gdv_int32 in) { return in; }
 
 static int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
diff --git a/cpp/src/gandiva/precompiled/types.h b/cpp/src/gandiva/precompiled/types.h
index a1a70de..9ddf9c1 100644
--- a/cpp/src/gandiva/precompiled/types.h
+++ b/cpp/src/gandiva/precompiled/types.h
@@ -33,6 +33,7 @@ using gdv_uint64 = uint64_t;
 using gdv_float32 = float;
 using gdv_float64 = double;
 using gdv_date64 = int64_t;
+using gdv_date32 = int32_t;
 using gdv_time32 = int32_t;
 using gdv_timestamp = int64_t;
 using gdv_utf8 = char*;
@@ -166,6 +167,10 @@ gdv_int32 utf8_length(gdv_int64 context, const char* data, gdv_int32 data_len);
 
 gdv_date64 castDATE_utf8(int64_t execution_context, const char* input, gdv_int32 length);
 
+gdv_date64 castDATE_int64(gdv_int64 date);
+
+gdv_date32 castDATE_int32(gdv_int32 date);
+
 gdv_timestamp castTIMESTAMP_utf8(int64_t execution_context, const char* input,
                                  gdv_int32 length);
 gdv_timestamp castTIMESTAMP_date64(gdv_date64);
diff --git a/cpp/src/gandiva/tests/date_time_test.cc b/cpp/src/gandiva/tests/date_time_test.cc
index a133c32..79b6109 100644
--- a/cpp/src/gandiva/tests/date_time_test.cc
+++ b/cpp/src/gandiva/tests/date_time_test.cc
@@ -26,10 +26,12 @@
 namespace gandiva {
 
 using arrow::boolean;
+using arrow::date32;
 using arrow::date64;
 using arrow::float32;
 using arrow::int32;
 using arrow::int64;
+using arrow::timestamp;
 
 class TestProjector : public ::testing::Test {
  public:
@@ -130,6 +132,42 @@ TEST_F(TestProjector, TestIsNull) {
   EXPECT_ARROW_ARRAY_EQUALS(exp_isnotnull, outputs.at(1));
 }
 
+TEST_F(TestProjector, TestDate32IsNull) {
+  auto d0 = field("d0", date32());
+  auto schema = arrow::schema({d0});
+
+  // output fields
+  auto b0 = field("isnull", boolean());
+
+  // isnull and isnotnull
+  auto isnull_expr = TreeExprBuilder::MakeExpression("isnull", {d0}, b0);
+
+  std::shared_ptr<Projector> projector;
+  auto status = Projector::Make(schema, {isnull_expr}, TestConfiguration(), &projector);
+  ASSERT_TRUE(status.ok());
+
+  int num_records = 4;
+  std::vector<int32_t> d0_data = {0, 100, 0, 1000};
+  auto validity = {false, true, false, true};
+  auto d0_array =
+      MakeArrowTypeArray<arrow::Date32Type, int32_t>(date32(), d0_data, validity);
+
+  // expected output
+  auto exp_isnull =
+      MakeArrowArrayBool({true, false, true, false}, {true, true, true, true});
+
+  // prepare input record batch
+  auto in_batch = arrow::RecordBatch::Make(schema, num_records, {d0_array});
+
+  // Evaluate expression
+  arrow::ArrayVector outputs;
+  status = projector->Evaluate(*in_batch, pool_, &outputs);
+  EXPECT_TRUE(status.ok());
+
+  // Validate results
+  EXPECT_ARROW_ARRAY_EQUALS(exp_isnull, outputs.at(0));
+}
+
 TEST_F(TestProjector, TestDateTime) {
   auto field0 = field("f0", date64());
   auto field2 = field("f2", timestamp(arrow::TimeUnit::MILLI));
diff --git a/cpp/src/gandiva/tree_expr_builder.cc b/cpp/src/gandiva/tree_expr_builder.cc
index 4f360e0..55941eb 100644
--- a/cpp/src/gandiva/tree_expr_builder.cc
+++ b/cpp/src/gandiva/tree_expr_builder.cc
@@ -91,6 +91,8 @@ NodePtr TreeExprBuilder::MakeNull(DataTypePtr data_type) {
     case arrow::Type::STRING:
     case arrow::Type::BINARY:
       return std::make_shared<LiteralNode>(data_type, LiteralHolder(empty), true);
+    case arrow::Type::DATE32:
+      return std::make_shared<LiteralNode>(data_type, LiteralHolder((int32_t)0), true);
     case arrow::Type::DATE64:
       return std::make_shared<LiteralNode>(data_type, LiteralHolder((int64_t)0), true);
     case arrow::Type::TIME32: