From 738b5fb8d897d4407d022353f6304e0548697aac Mon Sep 17 00:00:00 2001
From: Kostas Kyrimis <kostaskyrim@gmail.com>
Date: Wed, 15 Sep 2021 19:05:30 +0300
Subject: [PATCH] Add duration support for timestamp function (#236)

---
 src/query/interpret/awesome_memgraph_functions.cpp | 10 +++++++++-
 tests/unit/query_expression_evaluator.cpp          |  6 ++++++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/src/query/interpret/awesome_memgraph_functions.cpp b/src/query/interpret/awesome_memgraph_functions.cpp
index 8913ce043..c512d5358 100644
--- a/src/query/interpret/awesome_memgraph_functions.cpp
+++ b/src/query/interpret/awesome_memgraph_functions.cpp
@@ -88,6 +88,7 @@ struct Path {};
 struct Date {};
 struct LocalTime {};
 struct LocalDateTime {};
+struct Duration {};
 
 template <class ArgType>
 bool ArgIsType(const TypedValue &arg) {
@@ -125,6 +126,8 @@ bool ArgIsType(const TypedValue &arg) {
     return arg.IsLocalTime();
   } else if constexpr (std::is_same_v<ArgType, LocalDateTime>) {
     return arg.IsLocalDateTime();
+  } else if constexpr (std::is_same_v<ArgType, Duration>) {
+    return arg.IsDuration();
   } else if constexpr (std::is_same_v<ArgType, void>) {
     return true;
   } else {
@@ -173,6 +176,8 @@ constexpr const char *ArgTypeName() {
     return "LocalTime";
   } else if constexpr (std::is_same_v<ArgType, LocalDateTime>) {
     return "LocalDateTime";
+  } else if constexpr (std::is_same_v<ArgType, Duration>) {
+    return "Duration";
   } else {
     static_assert(std::is_same_v<ArgType, Null>, "Unknown ArgType");
   }
@@ -881,7 +886,7 @@ TypedValue ToString(const TypedValue *args, int64_t nargs, const FunctionContext
 }
 
 TypedValue Timestamp(const TypedValue *args, int64_t nargs, const FunctionContext &ctx) {
-  FType<Optional<Or<Date, LocalTime, LocalDateTime>>>("timestamp", args, nargs);
+  FType<Optional<Or<Date, LocalTime, LocalDateTime, Duration>>>("timestamp", args, nargs);
   const auto &arg = *args;
   if (arg.IsDate()) {
     return TypedValue(arg.ValueDate().MicrosecondsSinceEpoch(), ctx.memory);
@@ -892,6 +897,9 @@ TypedValue Timestamp(const TypedValue *args, int64_t nargs, const FunctionContex
   if (arg.IsLocalDateTime()) {
     return TypedValue(arg.ValueLocalDateTime().MicrosecondsSinceEpoch(), ctx.memory);
   }
+  if (arg.IsDuration()) {
+    return TypedValue(arg.ValueDuration().microseconds, ctx.memory);
+  }
   return TypedValue(ctx.timestamp, ctx.memory);
 }
 
diff --git a/tests/unit/query_expression_evaluator.cpp b/tests/unit/query_expression_evaluator.cpp
index 4ecdbbeec..451f9ddad 100644
--- a/tests/unit/query_expression_evaluator.cpp
+++ b/tests/unit/query_expression_evaluator.cpp
@@ -1762,6 +1762,12 @@ TEST_F(FunctionTest, TimestampLocalDateTime) {
   EXPECT_EQ(EvaluateFunction("TIMESTAMP", time).ValueInt(), 20000);
 }
 
+TEST_F(FunctionTest, TimestampDuration) {
+  ctx.timestamp = 42;
+  const utils::Duration time(20000);
+  EXPECT_EQ(EvaluateFunction("TIMESTAMP", time).ValueInt(), 20000);
+}
+
 TEST_F(FunctionTest, TimestampExceptions) {
   ctx.timestamp = 42;
   EXPECT_THROW(EvaluateFunction("TIMESTAMP", 1).ValueInt(), QueryRuntimeException);