Address temporal type epic comments (#249)
This commit is contained in:
parent
7e82cc6550
commit
d04e23805d
src
audit
query
storage/v2
utils
tests/e2e/temporal_types
@ -1,6 +1,7 @@
|
||||
#include "audit/log.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <sstream>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <json/json.hpp>
|
||||
@ -44,11 +45,34 @@ inline nlohmann::json PropertyValueToJson(const storage::PropertyValue &pv) {
|
||||
break;
|
||||
}
|
||||
case storage::PropertyValue::Type::TemporalData: {
|
||||
ret = nlohmann::json::object();
|
||||
const auto temporal_data = pv.ValueTemporalData();
|
||||
// TODO(antonio2368): Maybe we want to have custom format for each type
|
||||
ret.emplace("type", storage::TemporalTypeTostring(temporal_data.type));
|
||||
ret.emplace("microseconds", temporal_data.microseconds);
|
||||
auto to_string = [](auto temporal_data) {
|
||||
std::stringstream ss;
|
||||
const auto ms = temporal_data.microseconds;
|
||||
switch (temporal_data.type) {
|
||||
case storage::TemporalType::Date: {
|
||||
const auto date = utils::Date(ms);
|
||||
ss << date;
|
||||
return ss.str();
|
||||
}
|
||||
case storage::TemporalType::Duration: {
|
||||
const auto dur = utils::Duration(ms);
|
||||
ss << dur;
|
||||
return ss.str();
|
||||
}
|
||||
case storage::TemporalType::LocalTime: {
|
||||
const auto lt = utils::LocalTime(ms);
|
||||
ss << lt;
|
||||
return ss.str();
|
||||
}
|
||||
case storage::TemporalType::LocalDateTime: {
|
||||
const auto ldt = utils::LocalDateTime(ms);
|
||||
ss << ldt;
|
||||
return ss.str();
|
||||
}
|
||||
}
|
||||
};
|
||||
ret = to_string(temporal_data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "fmt/format.h"
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "query/db_accessor.hpp"
|
||||
#include "query/exceptions.hpp"
|
||||
|
@ -352,7 +352,7 @@ class ExpressionEvaluator : public ExpressionVisitor<TypedValue> {
|
||||
if (auto lt_field = maybe_local_time(ldt.local_time, prop_name); lt_field) {
|
||||
return std::move(*lt_field);
|
||||
}
|
||||
throw QueryRuntimeException("Invalid property named {} for LocalDateTime", prop_name);
|
||||
throw QueryRuntimeException("Invalid property name {} for LocalDateTime", prop_name);
|
||||
}
|
||||
default:
|
||||
throw QueryRuntimeException("Only nodes, edges, maps and temporal types have properties to be looked-up.");
|
||||
|
@ -274,8 +274,6 @@ mgp_value_type FromTypedValueType(query::TypedValue::Type type) {
|
||||
return MGP_VALUE_TYPE_LOCAL_DATE_TIME;
|
||||
case query::TypedValue::Type::Duration:
|
||||
return MGP_VALUE_TYPE_DURATION;
|
||||
default:
|
||||
LOG_FATAL("Unsupported value in the procedures");
|
||||
}
|
||||
}
|
||||
|
||||
@ -544,26 +542,22 @@ mgp_value::mgp_value(const storage::PropertyValue &pv, utils::MemoryResource *m)
|
||||
switch (temporal_data.type) {
|
||||
case storage::TemporalType::Date: {
|
||||
type = MGP_VALUE_TYPE_DATE;
|
||||
utils::Allocator<mgp_date> allocator(m);
|
||||
date_v = allocator.new_object<mgp_date>(temporal_data.microseconds);
|
||||
date_v = NewRawMgpObject<mgp_date>(m, temporal_data.microseconds);
|
||||
break;
|
||||
}
|
||||
case storage::TemporalType::LocalTime: {
|
||||
type = MGP_VALUE_TYPE_LOCAL_TIME;
|
||||
utils::Allocator<mgp_local_time> allocator(m);
|
||||
local_time_v = allocator.new_object<mgp_local_time>(temporal_data.microseconds);
|
||||
local_time_v = NewRawMgpObject<mgp_local_time>(m, temporal_data.microseconds);
|
||||
break;
|
||||
}
|
||||
case storage::TemporalType::LocalDateTime: {
|
||||
type = MGP_VALUE_TYPE_LOCAL_DATE_TIME;
|
||||
utils::Allocator<mgp_local_date_time> allocator(m);
|
||||
local_date_time_v = allocator.new_object<mgp_local_date_time>(temporal_data.microseconds);
|
||||
local_date_time_v = NewRawMgpObject<mgp_local_date_time>(m, temporal_data.microseconds);
|
||||
break;
|
||||
}
|
||||
case storage::TemporalType::Duration: {
|
||||
type = MGP_VALUE_TYPE_DURATION;
|
||||
utils::Allocator<mgp_duration> allocator(m);
|
||||
duration_v = allocator.new_object<mgp_duration>(temporal_data.microseconds);
|
||||
duration_v = NewRawMgpObject<mgp_duration>(m, temporal_data.microseconds);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -613,23 +607,19 @@ mgp_value::mgp_value(const mgp_value &other, utils::MemoryResource *m) : type(ot
|
||||
break;
|
||||
}
|
||||
case MGP_VALUE_TYPE_DATE: {
|
||||
utils::Allocator<mgp_date> allocator(m);
|
||||
date_v = allocator.new_object<mgp_date>(*other.date_v);
|
||||
date_v = NewRawMgpObject<mgp_date>(m, *other.date_v);
|
||||
break;
|
||||
}
|
||||
case MGP_VALUE_TYPE_LOCAL_TIME: {
|
||||
utils::Allocator<mgp_local_time> allocator(m);
|
||||
local_time_v = allocator.new_object<mgp_local_time>(*other.local_time_v);
|
||||
local_time_v = NewRawMgpObject<mgp_local_time>(m, *other.local_time_v);
|
||||
break;
|
||||
}
|
||||
case MGP_VALUE_TYPE_LOCAL_DATE_TIME: {
|
||||
utils::Allocator<mgp_local_date_time> allocator(m);
|
||||
local_date_time_v = allocator.new_object<mgp_local_date_time>(*other.local_date_time_v);
|
||||
local_date_time_v = NewRawMgpObject<mgp_local_date_time>(m, *other.local_date_time_v);
|
||||
break;
|
||||
}
|
||||
case MGP_VALUE_TYPE_DURATION: {
|
||||
utils::Allocator<mgp_duration> allocator(m);
|
||||
duration_v = allocator.new_object<mgp_duration>(*other.duration_v);
|
||||
duration_v = NewRawMgpObject<mgp_duration>(m, *other.duration_v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -754,8 +744,7 @@ mgp_value::mgp_value(mgp_value &&other, utils::MemoryResource *m) : type(other.t
|
||||
date_v = other.date_v;
|
||||
other.type = MGP_VALUE_TYPE_NULL;
|
||||
} else {
|
||||
utils::Allocator<mgp_date> allocator(m);
|
||||
date_v = allocator.new_object<mgp_date>(*other.date_v);
|
||||
date_v = NewRawMgpObject<mgp_date>(m, *other.date_v);
|
||||
}
|
||||
break;
|
||||
case MGP_VALUE_TYPE_LOCAL_TIME:
|
||||
@ -764,8 +753,7 @@ mgp_value::mgp_value(mgp_value &&other, utils::MemoryResource *m) : type(other.t
|
||||
local_time_v = other.local_time_v;
|
||||
other.type = MGP_VALUE_TYPE_NULL;
|
||||
} else {
|
||||
utils::Allocator<mgp_local_time> allocator(m);
|
||||
local_time_v = allocator.new_object<mgp_local_time>(*other.local_time_v);
|
||||
local_time_v = NewRawMgpObject<mgp_local_time>(m, *other.local_time_v);
|
||||
}
|
||||
break;
|
||||
case MGP_VALUE_TYPE_LOCAL_DATE_TIME:
|
||||
@ -775,8 +763,7 @@ mgp_value::mgp_value(mgp_value &&other, utils::MemoryResource *m) : type(other.t
|
||||
local_date_time_v = other.local_date_time_v;
|
||||
other.type = MGP_VALUE_TYPE_NULL;
|
||||
} else {
|
||||
utils::Allocator<mgp_local_date_time> allocator(m);
|
||||
local_date_time_v = allocator.new_object<mgp_local_date_time>(*other.local_date_time_v);
|
||||
local_date_time_v = NewRawMgpObject<mgp_local_date_time>(m, *other.local_date_time_v);
|
||||
}
|
||||
break;
|
||||
case MGP_VALUE_TYPE_DURATION:
|
||||
@ -785,8 +772,7 @@ mgp_value::mgp_value(mgp_value &&other, utils::MemoryResource *m) : type(other.t
|
||||
duration_v = other.duration_v;
|
||||
other.type = MGP_VALUE_TYPE_NULL;
|
||||
} else {
|
||||
utils::Allocator<mgp_duration> allocator(m);
|
||||
duration_v = allocator.new_object<mgp_duration>(*other.duration_v);
|
||||
duration_v = NewRawMgpObject<mgp_duration>(m, *other.duration_v);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1175,7 +1161,7 @@ mgp_error mgp_date_get_day(mgp_date *date, int *day) {
|
||||
}
|
||||
|
||||
mgp_error mgp_date_timestamp(mgp_date *date, int64_t *timestamp) {
|
||||
return WrapExceptions([date] { return static_cast<int>(date->date.MicrosecondsSinceEpoch()); }, timestamp);
|
||||
return WrapExceptions([date] { return date->date.MicrosecondsSinceEpoch(); }, timestamp);
|
||||
}
|
||||
|
||||
mgp_error mgp_date_now(mgp_memory *memory, mgp_date **date) {
|
||||
@ -1238,8 +1224,7 @@ mgp_error mgp_local_time_get_microsecond(mgp_local_time *local_time, int *micros
|
||||
}
|
||||
|
||||
mgp_error mgp_local_time_timestamp(mgp_local_time *local_time, int64_t *timestamp) {
|
||||
return WrapExceptions([local_time] { return static_cast<int>(local_time->local_time.MicrosecondsSinceEpoch()); },
|
||||
timestamp);
|
||||
return WrapExceptions([local_time] { return local_time->local_time.MicrosecondsSinceEpoch(); }, timestamp);
|
||||
}
|
||||
|
||||
mgp_error mgp_local_time_now(mgp_memory *memory, mgp_local_time **local_time) {
|
||||
@ -1301,7 +1286,7 @@ mgp_error mgp_local_date_time_get_year(mgp_local_date_time *local_date_time, int
|
||||
}
|
||||
|
||||
mgp_error mgp_local_date_time_get_month(mgp_local_date_time *local_date_time, int *month) {
|
||||
return WrapExceptions([local_date_time] { return local_date_time->local_date_time.date.month }, month);
|
||||
return WrapExceptions([local_date_time] { return local_date_time->local_date_time.date.month; }, month);
|
||||
}
|
||||
|
||||
mgp_error mgp_local_date_time_get_day(mgp_local_date_time *local_date_time, int *day) {
|
||||
@ -1331,9 +1316,8 @@ mgp_error mgp_local_date_time_get_microsecond(mgp_local_date_time *local_date_ti
|
||||
}
|
||||
|
||||
mgp_error mgp_local_date_time_timestamp(mgp_local_date_time *local_date_time, int64_t *timestamp) {
|
||||
return WrapExceptions(
|
||||
[local_date_time] { return static_cast<int>(local_date_time->local_date_time.MicrosecondsSinceEpoch()); },
|
||||
timestamp);
|
||||
return WrapExceptions([local_date_time] { return local_date_time->local_date_time.MicrosecondsSinceEpoch(); },
|
||||
timestamp);
|
||||
}
|
||||
|
||||
mgp_error mgp_local_date_time_now(mgp_memory *memory, mgp_local_date_time **local_date_time) {
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "indices.hpp"
|
||||
#include <limits>
|
||||
|
||||
#include "storage/v2/mvcc.hpp"
|
||||
#include "storage/v2/property_value.hpp"
|
||||
@ -521,7 +522,8 @@ const PropertyValue kSmallestNumber = PropertyValue(-std::numeric_limits<double>
|
||||
const PropertyValue kSmallestString = PropertyValue("");
|
||||
const PropertyValue kSmallestList = PropertyValue(std::vector<PropertyValue>());
|
||||
const PropertyValue kSmallestMap = PropertyValue(std::map<std::string, PropertyValue>());
|
||||
const PropertyValue kSmallestTemporalData = PropertyValue(TemporalData{static_cast<TemporalType>(0), 0});
|
||||
const PropertyValue kSmallestTemporalData =
|
||||
PropertyValue(TemporalData{static_cast<TemporalType>(0), std::numeric_limits<int64_t>::min()});
|
||||
|
||||
LabelPropertyIndex::Iterable::Iterable(utils::SkipList<Entry>::Accessor index_accessor, LabelId label,
|
||||
PropertyId property,
|
||||
|
@ -486,10 +486,7 @@ int64_t LocalDateTime::MicrosecondsSinceEpoch() const {
|
||||
|
||||
int64_t LocalDateTime::SecondsSinceEpoch() const {
|
||||
namespace chrono = std::chrono;
|
||||
const auto to_sec = chrono::duration_cast<chrono::seconds>(DaysSinceEpoch(date.year, date.month, date.day));
|
||||
const auto local_time_seconds =
|
||||
chrono::hours(local_time.hour) + chrono::minutes(local_time.minute) + chrono::seconds(local_time.second);
|
||||
return (to_sec + local_time_seconds).count();
|
||||
return chrono::duration_cast<chrono::seconds>(chrono::microseconds(MicrosecondsSinceEpoch())).count();
|
||||
}
|
||||
|
||||
int64_t LocalDateTime::SubSecondsAsNanoseconds() const {
|
||||
@ -500,7 +497,7 @@ int64_t LocalDateTime::SubSecondsAsNanoseconds() const {
|
||||
return (milli_as_nanos + micros_as_nanos).count();
|
||||
}
|
||||
|
||||
LocalDateTime::LocalDateTime(const DateParameters date_parameters, const LocalTimeParameters &local_time_parameters)
|
||||
LocalDateTime::LocalDateTime(const DateParameters &date_parameters, const LocalTimeParameters &local_time_parameters)
|
||||
: date(date_parameters), local_time(local_time_parameters) {}
|
||||
|
||||
LocalDateTime::LocalDateTime(const Date &date, const LocalTime &local_time) : date(date), local_time(local_time) {}
|
||||
|
@ -224,7 +224,7 @@ struct LocalTime {
|
||||
auto abs = [](auto value) { return (value >= 0) ? value : -value; };
|
||||
const auto lhs = local_time.MicrosecondsSinceEpoch();
|
||||
if (rhs < 0 && lhs < abs(rhs)) {
|
||||
constexpr int64_t one_day_in_microseconds = 24LL * 60 * 60 * 1000 * 1000;
|
||||
constexpr int64_t one_day_in_microseconds = chrono::duration_cast<chrono::microseconds>(chrono::days(1)).count();
|
||||
rhs = one_day_in_microseconds + rhs;
|
||||
}
|
||||
auto result = chrono::microseconds(lhs + rhs);
|
||||
@ -261,7 +261,7 @@ std::pair<DateParameters, LocalTimeParameters> ParseLocalDateTimeParameters(std:
|
||||
|
||||
struct LocalDateTime {
|
||||
explicit LocalDateTime(int64_t microseconds);
|
||||
explicit LocalDateTime(DateParameters date_parameters, const LocalTimeParameters &local_time_parameters);
|
||||
explicit LocalDateTime(const DateParameters &date_parameters, const LocalTimeParameters &local_time_parameters);
|
||||
explicit LocalDateTime(const Date &date, const LocalTime &local_time);
|
||||
|
||||
int64_t MicrosecondsSinceEpoch() const;
|
||||
|
@ -57,10 +57,10 @@ void RoundtripDate(mg::Client &client, const std::string_view group, const std::
|
||||
}
|
||||
|
||||
struct LocalTimeParams {
|
||||
int64_t hours{0};
|
||||
int64_t minutes{0};
|
||||
int64_t seconds{0};
|
||||
int64_t subseconds{0};
|
||||
int64_t hour{0};
|
||||
int64_t minute{0};
|
||||
int64_t second{0};
|
||||
int64_t subsecond{0};
|
||||
};
|
||||
|
||||
void RoundtripLocalTime(mg::Client &client, const std::string_view group, const std::string_view property,
|
||||
@ -162,8 +162,8 @@ void TestLocalDateTime(mg::Client &client) {
|
||||
utils::LocalDateTime({1960, 10, 1}, {}));
|
||||
RoundtripLocalDateTime(client, "Map_LDT2", "time", "{year:1960, month:10, day:1, hour:1, minute:2, second:33}",
|
||||
utils::LocalDateTime({1960, 10, 1}, {1, 2, 33}));
|
||||
RoundtripLocalDateTime(client, "Map_LDT3", "time", "{hour:10}", utils::LocalDateTime({}, {.hours = 10}));
|
||||
RoundtripLocalDateTime(client, "Map_LDT4", "time", "{day:2}", utils::LocalDateTime({.days = 2}, {}));
|
||||
RoundtripLocalDateTime(client, "Map_LDT3", "time", "{hour:10}", utils::LocalDateTime({}, {.hour = 10}));
|
||||
RoundtripLocalDateTime(client, "Map_LDT4", "time", "{day:2}", utils::LocalDateTime({.day = 2}, {}));
|
||||
}
|
||||
|
||||
void TestDuration(mg::Client &client) {
|
||||
@ -178,28 +178,26 @@ void TestDuration(mg::Client &client) {
|
||||
RoundtripDuration(client, "Runner5", "time", dur(0, 110, 14, 88, 400000), utils::Duration({0, 110, 14, 88, 400}));
|
||||
|
||||
// fractions
|
||||
RoundtripDuration(client, "Runner6", "time", "\"P4.5D\"", utils::Duration(utils::DurationParameters{.days = 4.5}));
|
||||
RoundtripDuration(client, "Runner7", "time", "\"PT9.3H\"", utils::Duration(utils::DurationParameters{.hours = 9.3}));
|
||||
RoundtripDuration(client, "Runner8", "time", "\"PT4.2M\"",
|
||||
utils::Duration(utils::DurationParameters{.minutes = 4.2}));
|
||||
RoundtripDuration(client, "Runner9", "time", "\"PT8.4S\"",
|
||||
utils::Duration(utils::DurationParameters{.seconds = 8.4}));
|
||||
RoundtripDuration(client, "Runner6", "time", "\"P4.5D\"", utils::Duration(utils::DurationParameters{.day = 4.5}));
|
||||
RoundtripDuration(client, "Runner7", "time", "\"PT9.3H\"", utils::Duration(utils::DurationParameters{.hour = 9.3}));
|
||||
RoundtripDuration(client, "Runner8", "time", "\"PT4.2M\"", utils::Duration(utils::DurationParameters{.minute = 4.2}));
|
||||
RoundtripDuration(client, "Runner9", "time", "\"PT8.4S\"", utils::Duration(utils::DurationParameters{.second = 8.4}));
|
||||
|
||||
RoundtripDuration(client, "RunnerMap1", "time",
|
||||
"{day:0, hour:4, minute:1, second:44, millisecond:44, microsecond:22}",
|
||||
utils::Duration(utils::DurationParameters{0, 4, 1, 44, 44, 22}));
|
||||
RoundtripDuration(client, "RunnerMap2", "time", "{day:15}", utils::Duration(utils::DurationParameters{15}));
|
||||
RoundtripDuration(client, "RunnerMap3", "time", "{hour:2.5}",
|
||||
utils::Duration(utils::DurationParameters{.hours = 2.5}));
|
||||
utils::Duration(utils::DurationParameters{.hour = 2.5}));
|
||||
RoundtripDuration(client, "RunnerMap4", "time", "{minute:10.5, second:44}",
|
||||
utils::Duration(utils::DurationParameters{.minutes = 10.5, .seconds = 44}));
|
||||
utils::Duration(utils::DurationParameters{.minute = 10.5, .second = 44}));
|
||||
|
||||
RoundtripDuration(client, "NegRunnerMap1", "time",
|
||||
"{day:0, hour:-1, minute:-2, second:-20, millisecond:-4, microsecond:-15}",
|
||||
utils::Duration(utils::DurationParameters{0, -1, -2, -20, -4, -15}));
|
||||
RoundtripDuration(client, "NegRunnerMap2", "time", "{day:-15}", utils::Duration(utils::DurationParameters{-15}));
|
||||
RoundtripDuration(client, "NegRunnerMap3", "time", "{hour:-2.5}",
|
||||
utils::Duration(utils::DurationParameters{.hours = -2.5}));
|
||||
utils::Duration(utils::DurationParameters{.hour = -2.5}));
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
Loading…
Reference in New Issue
Block a user