* Fix for execute write returning, closes#2762
* Fix stored write returning rowcount message
* Add configurable execute_write returning limit
* Return rows/truncated from execute query if it used RETURNING
* INSERT ... RETURNING shows rows in /-/execute-write
* Skip RETURNING tests if SQLite version does not support it
Screenshot: https://github.com/simonw/datasette/issues/2762#issuecomment-4588111545
Form submissions with multiple values for the same key (e.g. ``<select
multiple>``) previously had every value but the last silently discarded,
because ``post_vars()`` called ``dict(parse_qsl(...))``. Switch the
implementation to return a ``MultiParams`` object built from
``parse_qs(...)``, mirroring the existing ``request.args`` shape so both
sides of the GET/POST surface behave consistently.
``MultiParams`` gains an ``items()`` method that yields (key, first_value)
pairs, matching ``__getitem__`` semantics, so it works in patterns such as
``dict(post_vars())`` and the existing ``_coerce_execute_write_payload``
dict comprehension.
Internal callers of ``_json_or_form_payload`` (``execute_write`` and
``stored_queries``) had ``isinstance(data, dict)`` guards intended to
validate JSON shape but also rejected the new ``MultiParams`` return on
the form path. Gate those guards on ``is_json`` so the form path passes
through unchanged.
The bundled ``my_plugin`` test fixture wraps ``post_vars()`` in ``dict()``
before passing to ``Response.json``, demonstrating the migration path for
plugins that need a JSON-serialisable mapping.
Closes#2425
Expand the unreleased changelog with the deny-by-default operation analysis model, SQL function handling, and the VACUUM and virtual/shadow table restrictions for user-supplied write SQL.
Clarify the /-/execute-write JSON API documentation with the same restrictions and DDL permission requirements.
- Removed database_name and resource_name
- url can now optionally return JSON to reuse datasette.urls. methods
- description is now used as a truncated text description