]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
fix: raise DataError instead of OverflowError loading intervals too large
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Wed, 8 Jun 2022 22:12:20 +0000 (00:12 +0200)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Wed, 8 Jun 2022 23:01:57 +0000 (01:01 +0200)
This happened only for the binary format, not the text format.

docs/news.rst
psycopg/psycopg/types/datetime.py
psycopg_c/psycopg_c/types/datetime.pyx
tests/types/test_datetime.py

index 56cf42e24a6aae1c922f444c4ab967dfe7d087d2..8ca2802a7782486630008f3d308e228563a5786a 100644 (file)
@@ -16,6 +16,8 @@ Psycopg 3.0.15 (unreleased)
 - Fix wrong escaping of unprintable chars in COPY (nonetheless correctly
   interpreted by PostgreSQL).
 - Restore the connection to usable state after an error in `~Cursor.stream()`.
+- Raise `DataError` instead of `OverflowError` loading binary intervals
+  out-of-range.
 
 
 Current release
index d0a21606b7dca96b7195050f1bf1023eaf59204c..f791d44faaeacc8113ab6ca89ddc0082ce68e07d 100644 (file)
@@ -686,7 +686,11 @@ class IntervalBinaryLoader(Loader):
         elif months < 0:
             years, months = divmod(-months, 12)
             days = days - 30 * months - 365 * years
-        return timedelta(days=days, microseconds=micros)
+
+        try:
+            return timedelta(days=days, microseconds=micros)
+        except OverflowError as e:
+            raise DataError(f"can't parse interval: {e}") from None
 
 
 def _get_datestyle(conn: Optional["BaseConnection[Any]"]) -> bytes:
index b4eb7cd12dd164bb80fbf94be4011696730b6050..c8eb84230544eb07d4e414f4eee8d3e3fc5a4cca 100644 (file)
@@ -1006,7 +1006,10 @@ cdef class IntervalBinaryLoader(CLoader):
             usdays = -usdays
             us = -us
 
-        return cdt.timedelta_new(days + usdays, ussecs, us)
+        try:
+            return cdt.timedelta_new(days + usdays, ussecs, us)
+        except OverflowError as ex:
+            raise e.DataError(f"can't parse interval: {ex}")
 
 
 cdef const char *_parse_date_values(
index 108031fea65c4e603469b818edf676ac842fb3a8..889d492d3d7cb2f8ecc273f0b0fa9df4b3b1594a 100644 (file)
@@ -686,9 +686,10 @@ class TestInterval:
         cur.execute(f"select '{expr}'::interval")
         assert cur.fetchone()[0] == as_td(val)
 
+    @pytest.mark.parametrize("fmt_out", pq.Format)
     @pytest.mark.parametrize("val", ["min", "max"])
-    def test_load_interval_overflow(self, conn, val):
-        cur = conn.cursor()
+    def test_load_interval_overflow(self, conn, val, fmt_out):
+        cur = conn.cursor(binary=fmt_out)
         cur.execute(
             "select %s + %s * '1s'::interval",
             (as_td(val), -1 if val == "min" else 1),