to_bytes silently rescales a Decimal with a negative scale
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 78/100
Hướng nghiên cứu
Bắt đầu tại entry point pyiceberg.conversions.to_bytes và decimal_to_unscaled, sau đó chạy reproduction Decimal được cung cấp cho DecimalType(10, 2). Được xem là hoàn tất khi các scale có dấu không khớp bị từ chối thay vì được rescale, trong khi các giá trị đã khớp với scale của type vẫn round-trip chính xác; kiểm tra tác động lên pyiceberg/manifest.py và pyiceberg/io/pyarrow.py.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
to_bytes for DecimalType takes the absolute value of the exponent before comparing it
against the type's scale:
_, digits, exponent = value.as_tuple()
exponent = abs(int(exponent))
if exponent != primitive_type.scale:
raise ValueError(...)
A Decimal carries the negated scale as its exponent, so a value with a negative scale
passes this check as if it had the matching positive one. decimal_to_unscaled then uses
only the digits, and the exponent is dropped:
sign, digits, _ = value.as_tuple()
return int(Decimal((sign, digits, 0)).to_integral_value())
The value is written four orders of magnitude off, with no error.
Reproduction
from decimal import Decimal
from pyiceberg.conversions import to_bytes, from_bytes
from pyiceberg.types import DecimalType
t = DecimalType(10, 2)
print(from_bytes(t, to_bytes(t, Decimal("1E+2")))) # 0.01, expected 100.00
print(from_bytes(t, to_bytes(t, Decimal("5E+1")))) # 0.50 for decimal(10, 1) -> 0.5, expected 50.0
This is not an exotic input. Decimal.normalize() produces exactly this form:
Decimal("100").normalize() # Decimal('1E+2')
so a value that has been normalized, or that comes out of arithmetic that trims trailing
zeros, hits it.
Impact
to_bytes writes the lower_bounds and upper_bounds of a data file
(pyiceberg/manifest.py, _write_data_file_statistics), and the same conversion is used
in pyiceberg/io/pyarrow.py. A bound written as 0.01 instead of 100.00 makes scan
planning prune files that do hold matching rows, so a query silently returns fewer rows
than it should.
Values with a positive scale are unaffected: Decimal("100.00") round-trips correctly.
Suggested fix
Compare the signed scale, -exponent, against primitive_type.scale, so a mismatching
value is rejected instead of being silently rescaled. Rescaling the value to the type's
scale would be the other option, but that widens the contract of a function that today
requires an exact match.
Happy to open a PR.
- Ngôn ngữ chính
- Python
- Star
- 1.1k
- Fork
- 589
- Merge trung bình
- 1 ngày 20 giờ
- Pull request đã merge (30 ngày)
- 68
Hướng dẫn đóng góp
Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này
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/iceberg-python
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
apache/iceberg-python#4010 · 1 reaction ·
-
kind:bug
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 92/100
apache/iceberg-python#4006 ·
-
Deletion vector bitmap count is read from the blob and used as a loop bound without validation Đang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
apache/iceberg-python#3979 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
apache/iceberg-python#3885 ·
-
[Bug] PyArrowFileIO fails to propagate s3.ssl.ca-cert to pyarrow.fs.S3FileSystem tls_ca_file_path Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
apache/iceberg-python#3866 · 1 bình luận ·
Tất cả issue của apache/iceberg-python
Issue tương tự
-
[Bug] reef-hermes tells me to resume with hermes --resume, which does not work from my shell Đang mởarea: harness bug status: needs-triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
Human-Agent-Society/reef#625 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 80/100
learningequality/kolibri#15351 · 2 bình luận ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
-
Name consistency Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
eellak/triplestore#65 · 1 bình luận ·