]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
fix: don't forbid all PQexec queries in client-side cursors
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Thu, 12 May 2022 21:47:46 +0000 (23:47 +0200)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sun, 15 May 2022 09:15:30 +0000 (11:15 +0200)
We can still use PQexecParams with an empty list of parameters. This has
advantages, such as the possibility of implementing stream(), and less
faffing with differences between Cursor and ClientCursor.

psycopg/psycopg/client_cursor.py
psycopg/psycopg/cursor.py
tests/test_client_cursor.py
tests/test_client_cursor_async.py

index 851b1cec6830bef2214c04f7b6099980b8db9793..a61d10234383977e7248fbd34be943248a1f7d4d 100644 (file)
@@ -49,20 +49,23 @@ class ClientCursorMixin(BaseCursor[ConnectionType, Row]):
                 "client-side cursors don't support binary results"
             )
 
-        if no_pqexec:
-            raise e.NotSupportedError(
-                "PQexec operations not supported by client-side cursors"
-            )
-
         self._query = query
-        # if we don't have to, let's use exec_ as it can run more than
-        # one query in one go
-        if self._conn._pipeline:
-            self._conn._pipeline.command_queue.append(
-                partial(self._pgconn.send_query, query.query)
-            )
+        if no_pqexec:
+            if self._conn._pipeline:
+                self._conn._pipeline.command_queue.append(
+                    partial(self._pgconn.send_query_params, None)
+                )
+            else:
+                self._pgconn.send_query_params(query.query, None)
         else:
-            self._pgconn.send_query(query.query)
+            # if we don't have to, let's use exec_ as it can run more than
+            # one query in one go
+            if self._conn._pipeline:
+                self._conn._pipeline.command_queue.append(
+                    partial(self._pgconn.send_query, query.query)
+                )
+            else:
+                self._pgconn.send_query(query.query)
 
     def _convert_query(
         self, query: Query, params: Optional[Params] = None
@@ -76,9 +79,6 @@ class ClientCursorMixin(BaseCursor[ConnectionType, Row]):
     ) -> Tuple[Prepare, bytes]:
         return (Prepare.NO, b"")
 
-    def _is_pipeline_supported(self) -> bool:
-        return False
-
 
 class ClientCursor(ClientCursorMixin["Connection[Row]", Row], Cursor[Row]):
     pass
index 12db07a3fcc0ea727948eaaae400d9c63d377695..26d1611434558ef78bfaf04ad91f2499339e294b 100644 (file)
@@ -726,7 +726,7 @@ class Cursor(BaseCursor["Connection[Any]", Row]):
         Execute the same command with a sequence of input data.
         """
         try:
-            if self._is_pipeline_supported():
+            if Pipeline.is_supported():
                 # If there is already a pipeline, ride it, in order to avoid
                 # sending unnecessary Sync.
                 with self._conn.lock:
@@ -749,9 +749,6 @@ class Cursor(BaseCursor["Connection[Any]", Row]):
         except e.Error as ex:
             raise ex.with_traceback(None)
 
-    def _is_pipeline_supported(self) -> bool:
-        return Pipeline.is_supported()
-
     def stream(
         self,
         query: Query,
index dc5b22edb21ac64730aadf1a65074649b1d9261f..c2db78750d1f188f8033bdacd685fa52aaa988ce 100644 (file)
@@ -583,12 +583,14 @@ def test_query_params_executemany(conn):
 
 def test_stream(conn):
     cur = conn.cursor()
-    with pytest.raises(psycopg.NotSupportedError):
-        for rec in cur.stream(
-            "select i, '2021-01-01'::date + i from generate_series(1, %s) as i",
-            [2],
-        ):
-            pass
+    recs = []
+    for rec in cur.stream(
+        "select i, '2021-01-01'::date + i from generate_series(1, %s) as i",
+        [2],
+    ):
+        recs.append(rec)
+
+    assert recs == [(1, dt.date(2021, 1, 2)), (2, dt.date(2021, 1, 3))]
 
 
 class TestColumn:
index f4d7dc8bb3ab854fbf344f3b7b635d15eb2362d6..af8307ac94f709ec4ca873ee655dc1bce41a627e 100644 (file)
@@ -577,12 +577,14 @@ async def test_query_params_executemany(aconn):
 
 async def test_stream(aconn):
     cur = aconn.cursor()
-    with pytest.raises(psycopg.NotSupportedError):
-        async for rec in cur.stream(
-            "select i, '2021-01-01'::date + i from generate_series(1, %s) as i",
-            [2],
-        ):
-            pass
+    recs = []
+    async for rec in cur.stream(
+        "select i, '2021-01-01'::date + i from generate_series(1, %s) as i",
+        [2],
+    ):
+        recs.append(rec)
+
+    assert recs == [(1, dt.date(2021, 1, 2)), (2, dt.date(2021, 1, 3))]
 
 
 async def test_str(aconn):