1#include "duckdb/function/scalar/date_functions.hpp"
2#include "duckdb/common/types/time.hpp"
3#include "duckdb/common/types/timestamp.hpp"
4#include "duckdb/common/vector_operations/vector_operations.hpp"
5#include "duckdb/common/vector_operations/unary_executor.hpp"
6#include "duckdb/common/vector_operations/binary_executor.hpp"
7
8using namespace std;
9
10namespace duckdb {
11
12static const char *age_scalar_function(timestamp_t input1, timestamp_t input2, string &output) {
13 auto interval = Timestamp::GetDifference(input1, input2);
14 auto timestamp = Timestamp::IntervalToTimestamp(interval);
15 auto years = timestamp.year;
16 auto months = timestamp.month;
17 auto days = timestamp.day;
18 auto time = interval.time;
19
20 output = "";
21 if (years == 0 && months == 0 && days == 0) {
22 output += "00:00:00";
23 } else {
24 if (years != 0) {
25 output = std::to_string(years);
26 output += " years ";
27 }
28 if (months != 0) {
29 output += std::to_string(months);
30 output += " mons ";
31 }
32 if (days != 0) {
33 output += std::to_string(days);
34 output += " days";
35 }
36 if (time != 0) {
37 output += " ";
38 output += Time::ToString(time);
39 }
40 }
41 return output.c_str();
42}
43
44static void age_function_standard(DataChunk &input, ExpressionState &state, Vector &result) {
45 assert(input.column_count() == 1);
46 auto current_timestamp = Timestamp::GetCurrentTimestamp();
47
48 string output_buffer;
49 UnaryExecutor::Execute<timestamp_t, string_t, true>(input.data[0], result, input.size(), [&](timestamp_t input) {
50 return StringVector::AddString(result, age_scalar_function(input, current_timestamp, output_buffer));
51 });
52}
53
54static void age_function(DataChunk &input, ExpressionState &state, Vector &result) {
55 assert(input.column_count() == 2);
56
57 string output_buffer;
58 BinaryExecutor::Execute<timestamp_t, timestamp_t, string_t, true>(
59 input.data[0], input.data[1], result, input.size(), [&](timestamp_t input1, timestamp_t input2) {
60 return StringVector::AddString(result, age_scalar_function(input1, input2, output_buffer));
61 });
62}
63
64void AgeFun::RegisterFunction(BuiltinFunctions &set) {
65 ScalarFunctionSet age("age");
66 age.AddFunction(ScalarFunction({SQLType::TIMESTAMP}, SQLType::VARCHAR, age_function_standard));
67 age.AddFunction(ScalarFunction({SQLType::TIMESTAMP, SQLType::TIMESTAMP}, SQLType::VARCHAR, age_function));
68 set.AddFunction(age);
69}
70
71} // namespace duckdb
72