I realised I can use system_clock::time_point in my rows tuple
with the following ctype/conversion traits.
namespace arrow {
template <>
struct CTypeTraits<time_point<system_clock>> {
using ArrowType = ::arrow::TimestampType;
static std::shared_ptr<::arrow::DataType> type_singleton() {
return ::arrow::timestamp(::arrow::TimeUnit::NANO);
}
};
}
namespace arrow::stl {
template <>
struct ConversionTraits<time_point<system_clock>>
: public CTypeTraits<time_point<system_clock>> {
constexpr static bool nullable = false;
static Status AppendRow(
typename TypeTraits<TimestampType>::BuilderType& builder,
time_point<system_clock> cell) {
return builder.Append(
duration_cast<nanoseconds>(cell.time_since_epoch()).count());
}
static time_point<system_clock> GetEntry(const TimestampArray& array,
size_t j) {
return time_point<system_clock>(nanoseconds(array.Value(j)));
}
};
}
On Sun, 7 Apr 2024 at 22:47, Blair Azzopardi <[email protected]> wrote:
> Hi
>
> What timestamp type can I use when converting a table to a tuple (& vice
> versa)? I seem to have ended up with the c_type but this doesn't round
> trip. I'm wondering if I need to implement a ConversionTraits
> specialization. Also are there any existing helper functions for converting
> between arrow timestamp types and chrono time_points?
>
> The following snippet :
>
> inline Status Main() {
> auto read_options = json::ReadOptions::Defaults();
> auto parse_options = json::ParseOptions::Defaults();
> parse_options.unexpected_field_behavior =
> json::UnexpectedFieldBehavior::InferType;
>
> std::string json1 =
> R"({"a": 2.0, "b": "foo", "c": "2020-01-01"}
> {"a": -5.5, "b": null, "c": "2020-01-02"}
> )";
> ARROW_ASSIGN_OR_RAISE(auto tab1,
> ReadToTable(json1, read_options, parse_options));
> cout << tab1->ToString() << endl;
>
> // what should i use for my timestamp type to ensure round trip?
> vector<tuple<double, string, TimestampType::c_type>> rows(2);
>
> compute::ExecContext ctx;
> compute::CastOptions cast_options;
> if (!stl::TupleRangeFromTable(*tab1, cast_options, &ctx, &rows).ok()) {
> throw runtime_error("Failed to convert table to tuple range");
> }
>
> shared_ptr<Table> tab2;
> vector<string> names = {"A", "B", "C"};
> if (!stl::TableFromTupleRange(default_memory_pool(), rows, names,
> &tab2)
> .ok()) {
> throw runtime_error("Failed to convert tuple vector to table");
> }
> cout << tab2->ToString() << endl;
>
> return Status::OK();
> }
>
> outputs:
>
> a: double
> b: string
> c: timestamp[s]
> ----
> a:[[2, -5.5]]
> b:[["foo", null]]
> c:[[2020-01-01 00:00:00, 2020-01-02 00:00:00]]
>
> A: double not null
> B: string not null
> C: int64 not null
> ----
> A:[[2, -5.5]]
> B:[["foo", ""]]
> C:[[1577836800, 1577923200]]
>
> Ignoring null vs not-nulls, you can see the column c are integers.
>
> Thanks in advance!
>