diff --git a/docs/internals.rst b/docs/internals.rst index 0039fd12..036ccbe6 100644 --- a/docs/internals.rst +++ b/docs/internals.rst @@ -2067,6 +2067,9 @@ Write statements have a default time limit of 2,000ms. Pass a different value using ``time_limit_ms=`` or use ``time_limit_ms=None`` to allow the statement to run without a time limit. +This write limit is independent of the ``sql_time_limit_ms`` setting used for +read queries. Changing that setting does not change the default write limit. + .. _database_execute_write_script: await db.execute_write_script(sql, block=True) diff --git a/tests/test_internals_database.py b/tests/test_internals_database.py index 97513123..2500fa22 100644 --- a/tests/test_internals_database.py +++ b/tests/test_internals_database.py @@ -15,6 +15,7 @@ from datasette.database import ( DatasetteClosedError, ExecuteWriteResult, MultipleValues, + QueryInterrupted, Results, _deliver_write_result, ) @@ -478,6 +479,31 @@ async def test_view_names(db): ] +@pytest.mark.asyncio +async def test_execute_write_custom_time_limit(): + ds = Datasette(settings={"sql_time_limit_ms": 1}) + db = ds.add_memory_database(uuid.uuid4().hex, name="write_limits") + await ds.invoke_startup() + # Bounded work from PR #51; even without a limit this finishes on its own. + sql = ( + "with recursive c(x) as " + "(select 1 union all select x+1 from c where x < 800000) " + "select x from c where x < 0" + ) + try: + await db.execute_write("create table items(value integer)") + with pytest.raises(QueryInterrupted): + await db.execute(sql) + # Writes take their own explicit limit, independent of the read setting. + with pytest.raises(QueryInterrupted): + await db.execute_write(f"insert into items(value) {sql}", time_limit_ms=1) + # Interruption must leave the connection available for subsequent writes. + await db.execute_write("insert into items(value) values (1)") + assert (await db.execute("select value from items")).single_value() == 1 + finally: + ds.close() + + @pytest.mark.asyncio async def test_execute_write_block_true(db): result = await db.execute_write(