Skip to content

Commit

Permalink
ARROW-8334: [C++] [Gandiva] Missing DATE32 in LLVM Types
Browse files Browse the repository at this point in the history
Closes #6835 from durner/date32

Authored-by: Dominik Durner <durner@zoho.com>
Signed-off-by: Wes McKinney <wesm+git@apache.org>
  • Loading branch information
durner authored and wesm committed Apr 6, 2020
1 parent 739350e commit 6d92694
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 1 deletion.
1 change: 1 addition & 0 deletions cpp/src/gandiva/function_registry_arithmetic.cc
Expand Up @@ -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, {}),
Expand Down
3 changes: 2 additions & 1 deletion cpp/src/gandiva/function_registry_common.h
Expand Up @@ -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;
Expand Down Expand Up @@ -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) \
Expand Down
4 changes: 4 additions & 0 deletions cpp/src/gandiva/llvm_generator.cc
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions cpp/src/gandiva/llvm_types.cc
Expand Up @@ -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()},
Expand Down
2 changes: 2 additions & 0 deletions cpp/src/gandiva/precompiled/arithmetic_ops.cc
Expand Up @@ -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)

Expand Down Expand Up @@ -139,6 +140,7 @@ NUMERIC_TYPES(VALIDITY_OP, isnumeric, +)
INNER(float64)

#define DATE_FUNCTION(INNER) \
INNER(date32) \
INNER(date64) \
INNER(timestamp) \
INNER(time32)
Expand Down
1 change: 1 addition & 0 deletions cpp/src/gandiva/precompiled/hash.cc
Expand Up @@ -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)

Expand Down
3 changes: 3 additions & 0 deletions cpp/src/gandiva/precompiled/time.cc
Expand Up @@ -37,6 +37,7 @@ extern "C" {

// Expand inner macro for all date types.
#define DATE_TYPES(INNER) \
INNER(date32) \
INNER(date64) \
INNER(timestamp)

Expand Down Expand Up @@ -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};

Expand Down
5 changes: 5 additions & 0 deletions cpp/src/gandiva/precompiled/types.h
Expand Up @@ -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*;
Expand Down Expand Up @@ -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);
Expand Down
38 changes: 38 additions & 0 deletions cpp/src/gandiva/tests/date_time_test.cc
Expand Up @@ -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:
Expand Down Expand Up @@ -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));
Expand Down
2 changes: 2 additions & 0 deletions cpp/src/gandiva/tree_expr_builder.cc
Expand Up @@ -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:
Expand Down

0 comments on commit 6d92694

Please sign in to comment.