]> 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:03:01 +0000 (01:03 +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 441960e41d4cfc00315058ebdcd828558175300c..917c86e0a0d0728b41ce839d9755f1436a8d58b9 100644 (file)
@@ -36,6 +36,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 3a0394b8e0c88da7a0156008854b1fbc60705039..763a2340a6c6e2acfd8b2d9eea17e7641982b18a 100644 (file)
@@ -671,7 +671,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 68580204a1fd04f267d70e1e7cfe6a569f0aa0a0..b564709044b4ce0d1e3e4226f2142f04042d664d 100644 (file)
@@ -992,7 +992,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 4a8c56f2839d327532a8488e458a62814155bb99..66d026230b78b0e4c409868cabd11ec8dade4d9f 100644 (file)
@@ -681,9 +681,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),