Skip to content

feat(c/driver/postgresql): implement copy writer for time types#4057

Open
Gawaboumga wants to merge 4 commits intoapache:mainfrom
Gawaboumga:3841-Implement-COPY-Writer-support-for-time-(ms,-ns,-s)-types
Open

feat(c/driver/postgresql): implement copy writer for time types#4057
Gawaboumga wants to merge 4 commits intoapache:mainfrom
Gawaboumga:3841-Implement-COPY-Writer-support-for-time-(ms,-ns,-s)-types

Conversation

@Gawaboumga
Copy link

Hello,

I tried to implement the copy for postgresql for data types: time32 (s, ms) and time64 (us, ns). I may be one of the few using this ^^
I am not sure to fully grasp how work the ".txtcase" files.

Kind regards,

Closes #3841

@Gawaboumga Gawaboumga requested a review from lidavidm as a code owner March 8, 2026 11:05
@lidavidm lidavidm changed the title 3841 implement copy writer support for time (ms, ns, s) types feat(c/driver/postgresql): implement copy writer for time types Mar 9, 2026
Comment on lines +480 to +490
// Ensure the target type can hold the converted value (TIME32 -> int32).
if constexpr (std::is_same<OutT, int32_t>::value) {
if (out64 < (std::numeric_limits<int32_t>::min)() ||
out64 > (std::numeric_limits<int32_t>::max)()) {
ArrowErrorSet(error,
"[libpq] TIME value %" PRId64
" usec converts to %" PRId64
" which overflows int32 for Arrow TIME32",
time_usec, out64);
return EOVERFLOW;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this possible given we're already validating that the value fits in 24 hours?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, this should never happen.

const int32_t out32 = static_cast<int32_t>(out64);
NANOARROW_RETURN_NOT_OK(ArrowBufferAppend(data_, &out32, sizeof(out32)));
} else {
const int64_t out = static_cast<int64_t>(out64);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: redundant cast?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the symmetry and avoided the redundant cast.

break;
}

if (micros < 0 || micros > kUsecsPerDay) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. If we assume the Arrow data isn't necessarily valid, don't we have to watch for overflow when we do the multiplication above? Or if we do assume the data is valid, then this can't happen, right?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reused the overflow validation logic of Duration or Timestamp

- Since we already ensure that time is within a day, it is not mandatory
- const int64_t out = static_cast<int64_t>(out64); is a redundant cast
- Fix ODR of constants
- Reuse overflow validation logic
Copy link
Member

@lidavidm lidavidm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

},
{
"name": "value",
"format": "ttm",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"format": "ttm",
"format": "ttu",

We always read microseconds, so let's expect microseconds (also the values below need to be adjusted)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"format": "+s",
"children": [
{
"name": "value",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Field name should be "res"

"children": [
{
"name": "value",
"format": "ttm",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expect you will need microseconds here and below

Comment on lines +37 to +44
// part: expected

{"idx": 0, "value": null}
{"idx": 1, "value": 0}
{"idx": 2, "value": 1}
{"idx": 3, "value": 3723123456}
{"idx": 4, "value": 86399999999}
{"idx": 5, "value": 86400000000}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears these values do not line up with what's expected (https://github.com/adbc-drivers/validation/blob/main/adbc_drivers_validation/queries/ingest/time_us.txtcase)

Frankly there should be no need to override this case?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

c/driver/postgresql: Implement COPY Writer support for time (ms, ns, s) types

2 participants