From: Daniele Varrazzo Date: Tue, 15 Aug 2023 18:18:12 +0000 (+0100) Subject: refactor(tests): generate sync prepared statements tests from async side X-Git-Tag: pool-3.2.0~12^2~52 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=267d167d15e6043b9ecc2c4f3812206248f2b523;p=thirdparty%2Fpsycopg.git refactor(tests): generate sync prepared statements tests from async side --- diff --git a/tests/test_prepared.py b/tests/test_prepared.py index 56c580a9f..eb34a1b11 100644 --- a/tests/test_prepared.py +++ b/tests/test_prepared.py @@ -1,3 +1,6 @@ +# WARNING: this file is auto-generated by 'async_to_sync.py' +# from the original file 'test_prepared_async.py' +# DO NOT CHANGE! Change the original file instead. """ Prepared statements tests """ @@ -131,9 +134,7 @@ def test_misc_statement(conn, query): def test_params_types(conn): conn.execute( - "select %s, %s, %s", - [dt.date(2020, 12, 10), 42, Decimal(42)], - prepare=True, + "select %s, %s, %s", [dt.date(2020, 12, 10), 42, Decimal(42)], prepare=True ) stmts = get_prepared_statements(conn) want = [stmt.parameter_types for stmt in stmts] @@ -191,7 +192,6 @@ def test_different_types(conn): def test_untyped_json(conn): conn.prepare_threshold = 1 conn.execute("create table testjson(data jsonb)") - for i in range(2): conn.execute("insert into testjson (data) values (%s)", ["{}"]) @@ -262,11 +262,11 @@ def test_change_type_savepoint(conn): def get_prepared_statements(conn): cur = conn.cursor(row_factory=namedtuple_row) + # CRDB has 'PREPARE name AS' in the statement. cur.execute( - # CRDB has 'PREPARE name AS' in the statement. - r""" + """ select name, - regexp_replace(statement, 'prepare _pg3_\d+ as ', '', 'i') as statement, + regexp_replace(statement, 'prepare _pg3_\\d+ as ', '', 'i') as statement, prepare_time, parameter_types from pg_prepared_statements diff --git a/tests/test_prepared_async.py b/tests/test_prepared_async.py index afe7d4db5..ef0c57605 100644 --- a/tests/test_prepared_async.py +++ b/tests/test_prepared_async.py @@ -1,5 +1,5 @@ """ -Prepared statements tests on async connections +Prepared statements tests """ import datetime as dt @@ -89,6 +89,16 @@ async def test_no_prepare_multi(aconn): assert res == [0] * 10 +async def test_no_prepare_multi_with_drop(aconn): + await aconn.execute("select 1", prepare=True) + + for i in range(10): + await aconn.execute("drop table if exists noprep; create table noprep()") + + stmts = await get_prepared_statements(aconn) + assert len(stmts) == 0 + + async def test_no_prepare_error(aconn): await aconn.set_autocommit(True) for i in range(10): @@ -189,12 +199,77 @@ async def test_untyped_json(aconn): assert got == [["jsonb"]] +async def test_change_type_execute(aconn): + aconn.prepare_threshold = 0 + for i in range(3): + await aconn.execute("CREATE TYPE prepenum AS ENUM ('foo', 'bar', 'baz')") + await aconn.execute("CREATE TABLE preptable(id integer, bar prepenum[])") + await aconn.cursor().execute( + "INSERT INTO preptable (bar) VALUES (%(enum_col)s::prepenum[])", + {"enum_col": ["foo"]}, + ) + await aconn.rollback() + + +async def test_change_type_executemany(aconn): + for i in range(3): + await aconn.execute("CREATE TYPE prepenum AS ENUM ('foo', 'bar', 'baz')") + await aconn.execute("CREATE TABLE preptable(id integer, bar prepenum[])") + await aconn.cursor().executemany( + "INSERT INTO preptable (bar) VALUES (%(enum_col)s::prepenum[])", + [{"enum_col": ["foo"]}, {"enum_col": ["foo", "bar"]}], + ) + await aconn.rollback() + + +@pytest.mark.crdb("skip", reason="can't re-create a type") +async def test_change_type(aconn): + aconn.prepare_threshold = 0 + await aconn.execute("CREATE TYPE prepenum AS ENUM ('foo', 'bar', 'baz')") + await aconn.execute("CREATE TABLE preptable(id integer, bar prepenum[])") + await aconn.cursor().execute( + "INSERT INTO preptable (bar) VALUES (%(enum_col)s::prepenum[])", + {"enum_col": ["foo"]}, + ) + await aconn.execute("DROP TABLE preptable") + await aconn.execute("DROP TYPE prepenum") + await aconn.execute("CREATE TYPE prepenum AS ENUM ('foo', 'bar', 'baz')") + await aconn.execute("CREATE TABLE preptable(id integer, bar prepenum[])") + await aconn.cursor().execute( + "INSERT INTO preptable (bar) VALUES (%(enum_col)s::prepenum[])", + {"enum_col": ["foo"]}, + ) + + stmts = await get_prepared_statements(aconn) + assert len(stmts) == 3 + + +async def test_change_type_savepoint(aconn): + aconn.prepare_threshold = 0 + async with aconn.transaction(): + for i in range(3): + with pytest.raises(ZeroDivisionError): + async with aconn.transaction(): + await aconn.execute( + "CREATE TYPE prepenum AS ENUM ('foo', 'bar', 'baz')" + ) + await aconn.execute( + "CREATE TABLE preptable(id integer, bar prepenum[])" + ) + await aconn.cursor().execute( + "INSERT INTO preptable (bar) VALUES (%(enum_col)s::prepenum[])", + {"enum_col": ["foo"]}, + ) + raise ZeroDivisionError() + + async def get_prepared_statements(aconn): cur = aconn.cursor(row_factory=namedtuple_row) + # CRDB has 'PREPARE name AS' in the statement. await cur.execute( - r""" + """ select name, - regexp_replace(statement, 'prepare _pg3_\d+ as ', '', 'i') as statement, + regexp_replace(statement, 'prepare _pg3_\\d+ as ', '', 'i') as statement, prepare_time, parameter_types from pg_prepared_statements diff --git a/tools/convert_async_to_sync.sh b/tools/convert_async_to_sync.sh index f71354028..c531c4771 100755 --- a/tools/convert_async_to_sync.sh +++ b/tools/convert_async_to_sync.sh @@ -14,6 +14,7 @@ for async in \ tests/test_cursor_async.py \ tests/test_default_cursor_async.py \ tests/test_pipeline_async.py \ + tests/test_prepared_async.py \ tests/test_raw_cursor_async.py \ tests/test_server_cursor_async.py do