From: Daniele Varrazzo Date: Tue, 30 Jun 2020 17:58:08 +0000 (+1200) Subject: Handle a bad command passed to copy X-Git-Tag: 3.0.dev0~473 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e30fc3981b313f932a35cfd06dff700cefc75488;p=thirdparty%2Fpsycopg.git Handle a bad command passed to copy --- diff --git a/psycopg3/cursor.py b/psycopg3/cursor.py index 8ee944658..fd4e60252 100644 --- a/psycopg3/cursor.py +++ b/psycopg3/cursor.py @@ -261,10 +261,16 @@ class BaseCursor: result = results[0] status = result.status - if status not in (pq.ExecStatus.COPY_IN, pq.ExecStatus.COPY_OUT): + if status in (pq.ExecStatus.COPY_IN, pq.ExecStatus.COPY_OUT): + return + elif status == pq.ExecStatus.FATAL_ERROR: + raise e.error_from_result( + result, encoding=self.connection.codec.name + ) + else: raise e.ProgrammingError( - "copy() should be used only with COPY ... TO STDOUT" - " or COPY ... FROM STDIN statements" + "copy() should be used only with COPY ... TO STDOUT or COPY ..." + f" FROM STDIN statements, got {pq.ExecStatus(status).name}" ) diff --git a/tests/test_copy.py b/tests/test_copy.py index 3e256df6a..e739f1985 100644 --- a/tests/test_copy.py +++ b/tests/test_copy.py @@ -69,6 +69,21 @@ def test_copy_in_buffers_pg_error(conn): assert conn.pgconn.transaction_status == conn.TransactionStatus.INERROR +def test_copy_bad_result(conn): + conn.autocommit = True + + cur = conn.cursor() + + with pytest.raises(e.SyntaxError): + cur.copy("wat") + + with pytest.raises(e.ProgrammingError): + cur.copy("select 1") + + with pytest.raises(e.ProgrammingError): + cur.copy("reset timezone") + + @pytest.mark.parametrize( "format, buffer", [(Format.TEXT, "sample_text"), (Format.BINARY, "sample_binary")], diff --git a/tests/test_copy_async.py b/tests/test_copy_async.py index cce63aab5..289a6c428 100644 --- a/tests/test_copy_async.py +++ b/tests/test_copy_async.py @@ -72,6 +72,21 @@ async def test_copy_in_buffers_pg_error(aconn): assert aconn.pgconn.transaction_status == aconn.TransactionStatus.INERROR +async def test_copy_bad_result(conn): + conn.autocommit = True + + cur = conn.cursor() + + with pytest.raises(e.SyntaxError): + await cur.copy("wat") + + with pytest.raises(e.ProgrammingError): + await cur.copy("select 1") + + with pytest.raises(e.ProgrammingError): + await cur.copy("reset timezone") + + @pytest.mark.parametrize( "format, buffer", [(Format.TEXT, "sample_text"), (Format.BINARY, "sample_binary")],