execute_isolated_fn() always opened its temporary connection with
write=True, which is not allowed for immutable databases - so APIs
that rely on it, like SQL analysis when storing a query, failed.
An immutable database can never receive writes, so there is no write
queue to block: in that case the function now opens a read-only
connection and runs it on the executor, bypassing the write thread
entirely. Mutable databases keep the existing write-thread behavior.
Also fixed a latent bug in the write thread where a connect() failure
for an isolated task would crash the thread instead of delivering the
exception back to the caller.
Closes#2768
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Add web UI to edit and delete stored queries
Stored query pages now offer Edit and Delete actions in the query
actions menu, gated by the update-query and delete-query permissions.
- New QueryEditView (GET/POST at /<db>/<query>/-/edit) renders a
pre-filled form for editing a query's title, description, SQL and
privacy, reusing the create-query analysis UI. Changing the SQL still
requires execute-sql; metadata-only edits do not.
- QueryDeleteView gains a GET confirmation page and HTML form POST that
redirects to the query list, while keeping the existing JSON API.
- New default query_actions hook adds the Edit/Delete links for stored
(non-config, non-trusted) queries the actor is allowed to manage.
Permission semantics (already enforced by default_query_permissions_sql)
are surfaced in the UI: owners can always edit/delete their queries;
non-private queries can be edited/deleted by any actor with the relevant
permission; private queries remain owner-only.
Shared the create-query form styles into _query_form_styles.html so the
edit form can reuse them.
Animated demo: https://github.com/simonw/datasette/pull/2764#issuecomment-4655694668Closes#2760https://claude.ai/code/session_019GU9g3pZAERukLKYNa4uAL
* 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
Private means it has an owner, and the config does not let
you say who the owner is - plus configured queries should
not be possible to edit or delete in the UI so having an
owner makes even less sense.
You can still make configured queries visible to specific
people using regular view-query permissions.
Stop marking sqlite_master and sqlite_schema reads as internal as soon as the SQLite authorizer reports them. The later DDL-aware pass still treats schema catalog access as internal when it accompanies semantic CREATE, ALTER, or DROP operations.
This makes explicit catalog reads in write SQL fall through to the deny-by-default path as unsupported read schema operations, preventing queries from copying private table definitions into writable tables.
Refs https://github.com/simonw/datasette/pull/2749#issuecomment-4559073803
Raw SQL insert and update statements can have broader effects than their SQLite authorizer callbacks reveal. INSERT OR REPLACE and UPDATE OR REPLACE can delete conflicting rows while only surfacing insert or update operations.
Expand table insert and update operations to require insert-row, update-row, and delete-row together. Keep delete operations mapped to delete-row, and update the analysis UI/API to report and evaluate multiple required permissions for a single operation.
Refs https://github.com/simonw/datasette/pull/2749#issuecomment-4559083539
Require view-table permission for reads discovered inside write SQL analysis, including INSERT ... SELECT and CREATE TABLE ... AS SELECT.
Record additional SQLite authorizer callbacks as Operation values so unsupported functions, savepoints, virtual table DDL, and unknown callbacks are denied unless explicitly handled.
view-query is back in the default allow actions now. We have
other mechanisms that work for controlling visibility, and
the fact that queries default to running with the permissions
of the actor makes this safe.
- Start with a template option, letting you pick table and operation
- SQL textarea defaults to 4 empty lines at start
- Query operations table is simpler and looks nicer
Refs #2742