]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
fix: fix AsyncClientCursor.rownumber after scroll() 1066/head
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sun, 4 May 2025 17:03:38 +0000 (19:03 +0200)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sun, 4 May 2025 17:37:17 +0000 (19:37 +0200)
docs/news.rst
psycopg/psycopg/_server_cursor_async.py
tests/test_cursor_server.py
tests/test_cursor_server_async.py

index 731ee047c6a48532430ad5e8e5e7fbbd675306f7..a6bf02ae706652caf3643ccb2c76d8c74efbd390 100644 (file)
@@ -13,10 +13,12 @@ Future releases
 Psycopg 3.2.8 (unreleased)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-- Fix `DateFromTicks` and `TimeFromTicks` return values to return date and
-  time referred as UTC rather than the local timezone. Change
-  `TimestampFromTicks` to return a datetime in UTC rather than in the local
-  timezone (:ticket:`#1058`).
+- Fix `DateFromTicks` and `TimeFromTicks` return values to return a date and a
+  time referred to the UTC timezone rather than to the local timezone. For
+  consistency, `TimestampFromTicks` to return a datetime in UTC rather than in
+  the local timezone (:ticket:`#1058`).
+- Fix `~Cursor.rownumber` after using `~AsyncServerCursor.scroll()` on
+  `AsyncServerCursor` (:ticket:`#1066`).
 
 
 Current release
index 7ac9baff88146e4b30602402ae2fc4c681dcc321..37e0e2621e0abff08d9ba310bf07fec9d1f7bd51 100644 (file)
@@ -149,3 +149,8 @@ class AsyncServerCursor(
     async def scroll(self, value: int, mode: str = "relative") -> None:
         async with self._conn.lock:
             await self._conn.wait(self._scroll_gen(value, mode))
+        # Postgres doesn't have a reliable way to report a cursor out of bound
+        if mode == "relative":
+            self._pos += value
+        else:
+            self._pos = value
index d5342a689035c8ad5b5f28c7fa44ab3e265ea157..cc2d4cb5e4738b5314ec2346fba1b60187cc370a 100644 (file)
@@ -382,10 +382,14 @@ def test_row_factory(conn):
 
     cur = conn.cursor("foo", row_factory=my_row_factory, scrollable=True)
     cur.execute("select generate_series(1, 3) as x")
+    assert cur.rownumber == 0
     recs = cur.fetchall()
+    assert cur.rownumber == 3
     cur.scroll(0, "absolute")
+    assert cur.rownumber == 0
     while rec := cur.fetchone():
         recs.append(rec)
+    assert cur.rownumber == 3
     assert recs == [[1, -1], [1, -2], [1, -3]] * 2
 
     cur.scroll(0, "absolute")
@@ -458,17 +462,26 @@ def test_cant_scroll_by_default(conn):
 def test_scroll(conn):
     cur = conn.cursor("tmp", scrollable=True)
     cur.execute("select generate_series(0,9)")
+    assert cur.rownumber == 0
     cur.scroll(2)
+    assert cur.rownumber == 2
     assert cur.fetchone() == (2,)
+    assert cur.rownumber == 3
     cur.scroll(2)
+    assert cur.rownumber == 5
     assert cur.fetchone() == (5,)
+    assert cur.rownumber == 6
     cur.scroll(2, mode="relative")
+    assert cur.rownumber == 8
     assert cur.fetchone() == (8,)
     cur.scroll(9, mode="absolute")
+    assert cur.rownumber == 9
     assert cur.fetchone() == (9,)
+    assert cur.rownumber == 10
 
     with pytest.raises(ValueError):
         cur.scroll(9, mode="wat")
+        assert cur.rownumber == 10
     cur.close()
 
 
index 682859984172a971202108eb4aa6720b4d47876d..98ae9a27857bea3cbbdab6f81f31d537a9987ff8 100644 (file)
@@ -388,10 +388,14 @@ async def test_row_factory(aconn):
 
     cur = aconn.cursor("foo", row_factory=my_row_factory, scrollable=True)
     await cur.execute("select generate_series(1, 3) as x")
+    assert cur.rownumber == 0
     recs = await cur.fetchall()
+    assert cur.rownumber == 3
     await cur.scroll(0, "absolute")
+    assert cur.rownumber == 0
     while rec := (await cur.fetchone()):
         recs.append(rec)
+    assert cur.rownumber == 3
     assert recs == [[1, -1], [1, -2], [1, -3]] * 2
 
     await cur.scroll(0, "absolute")
@@ -464,17 +468,26 @@ async def test_cant_scroll_by_default(aconn):
 async def test_scroll(aconn):
     cur = aconn.cursor("tmp", scrollable=True)
     await cur.execute("select generate_series(0,9)")
+    assert cur.rownumber == 0
     await cur.scroll(2)
+    assert cur.rownumber == 2
     assert await cur.fetchone() == (2,)
+    assert cur.rownumber == 3
     await cur.scroll(2)
+    assert cur.rownumber == 5
     assert await cur.fetchone() == (5,)
+    assert cur.rownumber == 6
     await cur.scroll(2, mode="relative")
+    assert cur.rownumber == 8
     assert await cur.fetchone() == (8,)
     await cur.scroll(9, mode="absolute")
+    assert cur.rownumber == 9
     assert await cur.fetchone() == (9,)
+    assert cur.rownumber == 10
 
     with pytest.raises(ValueError):
         await cur.scroll(9, mode="wat")
+        assert cur.rownumber == 10
     await cur.close()