Date32 getDateDay silently loses precision for dates outside ~1685-2255
Maintainer thường phản hồi trong vòng 4 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 50/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Ít trao đổi
- Công nghệ
- javascript
- Lĩnh vực
- data
Hướng nghiên cứu
Bắt đầu trong visitor/get.mjs bằng cách đọc epochDaysToMs và getDateDay, sau đó so sánh hành vi của chúng với visitInt32. Xác nhận getter hiện biểu diễn các giá trị Date32 như thế nào và xác định liệu việc trả về số ngày int32 thô có bảo toàn phạm vi dự kiến hay không; hoàn tất khi mất độ chính xác được loại bỏ mà không để hành vi của breaking change chưa được giải quyết.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Summary
getDateDay converts int32 day values to epoch milliseconds via 86400000 * data[index]. This overflows Number.MAX_SAFE_INTEGER for dates far from epoch, silently returning incorrect values.
Root cause
In visitor/get.mjs:
const epochDaysToMs = (data, index) => 86400000 * data[index];
const getDateDay = ({ values }, index) => epochDaysToMs(values, index);
Date32 stores days as int32, supporting a range of ±2^31 days (~5.8 million years in each direction). But 86400000 * 2147483647 = 1.855e17, which exceeds Number.MAX_SAFE_INTEGER (9.007e15).
The precision boundary is Math.floor(Number.MAX_SAFE_INTEGER / 86400000) = 104,249,991 days ≈ ±285,420 years from epoch. Dates outside roughly 283,400 BC – 287,400 AD silently return incorrect millisecond values due to floating-point precision loss.
Impact
Unlike the timestamp overflow (which throws — see #421), this silently returns wrong data. DuckDB's DATE type supports dates from 5,877,642 BC to 5,881,580 AD. DuckDB's test_all_types() produces min/max dates well outside the safe conversion range. Consumers displaying these dates get subtly wrong output with no error.
Additionally, DuckDB uses date infinity sentinels (INT32_MAX and -INT32_MAX) which also overflow when multiplied by 86400000.
Proposal
Return the raw int32 day count instead of converting to milliseconds:
const getDateDay = ({ values }, index) => values[index];
This is lossless, never overflows, and consistent with how visitInt32 already returns the raw value. Callers that want a JS Date can convert explicitly:
new Date(days * 86400000) // fine for dates within ±285k years
As with #421, this is a breaking change for code that expects get() to return epoch milliseconds. The same resolution options apply (major version bump, opt-in flag, etc.).
Context
We hit this building a DuckDB WASM frontend that renders test_all_types(). Our workaround reads raw int32 values from the underlying Int32Array:
if (typeStr.includes("Date32")) {
const chunk = column.data?.[0] ?? column.data;
if (chunk?.values instanceof Int32Array) {
return chunk.values[row - (chunk.offset ?? 0)]; // raw days
}
}
This bypasses Arrow's getter entirely. We then format using Howard Hinnant's civil calendar algorithm, which handles the full int32 day range correctly with pure arithmetic.
- Ngôn ngữ chính
- TypeScript
- Star
- 112
- Fork
- 23
- Merge trung bình
- 1 ngày 10 giờ
- Pull request đã merge (30 ngày)
- 13
Chuẩn bị môi trường
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của apache/arrow-js
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
Maintainer thường phản hồi trong vòng 4 ngày
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 68/100
apache/arrow-js#484 · 1 bình luận · 1 reaction ·
Maintainer thường phản hồi trong vòng 4 ngày
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 55/100
apache/arrow-js#468 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 4 ngày
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 35/100
Maintainer thường phản hồi trong vòng 4 ngày
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
apache/arrow-js#423 · 1 reaction ·
Maintainer thường phản hồi trong vòng 4 ngày
Tất cả issue của apache/arrow-js
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
rohitg00/agentmemory#1428 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
boxlite-ai/boxlite#1729 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Detect Deno tasks from deno.jsonĐang mởdetectors enhancement good first issue
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
SM260845/readme-gen#1 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
angular/angularfire#3774 ·
Maintainer thường phản hồi trong vòng 2 ngày