Skip to content

feat(workspace): return query results from the execute statement command - #879

Open
psteinroe wants to merge 2 commits into
mainfrom
fix/execute-statement-results
Open

psteinroe wants to merge 2 commits into
mainfrom
fix/execute-statement-results

Conversation

@psteinroe

@psteinroe psteinroe commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

The execute statement code action now returns the rows a statement produces, and when it is disabled it says which setting enables it. Before, a select only reported "Rows affected: N", and a disabled action only said "Statement execution is disabled in the settings." This PR also removes two panics on user configuration in DatabaseSettings: an invalid glob in allowStatementExecutionsAgainst and an invalid connectionString.

Result payload

workspace/executeCommand for pgls.executeStatement now returns a structured result (it returned null before) and still shows a short summary with showMessage:

// select id, name from users
{ "message": "2 rows", "columns": ["id", "name"], "rows": [["1", "Alice"], ["2", null]], "truncated": false }

// insert into users ...
{ "message": "Successfully executed statement. Rows affected: 2", "columns": [], "rows": [], "truncated": false, "rowsAffected": 2 }

The statement now runs over the simple query protocol (sqlx::raw_sql) instead of as a prepared statement. That way Postgres sends every value in its text form, the same output psql shows, so arrays, intervals, jsonb, and custom types need no decoding. At most 100 rows are returned, and truncated marks larger results. Postgres sends no column metadata with an empty result. So when nothing was returned and nothing was affected, the statement is described afterwards to tell a 0-row query (columns set) apart from a command (rowsAffected set). The payload is documented in docs/guides/configure_database.md for extension authors. The VS Code extension (supabase-community/postgres-language-server-vscode) needs a follow-up to render it.

Disabled reason and invalid patterns

The reason now reads: "Statement execution is disabled for 127.0.0.1/postgres. Add a matching pattern to db.allowStatementExecutionsAgainst, e.g. ["127.0.0.1/*"]." An invalid glob in allowStatementExecutionsAgainst used to panic the server. Now it is ignored, a warning is logged, and the disabled reason lists it.

Invalid connection string

An unparsable db.connectionString (or DATABASE_URL) used to panic while loading the settings, which crashed check and the language server on startup or on a config reload. Now it disables the database connection, as if no host were configured, and logs a warning. check reports it like a failed connection and exits non-zero:

database/connection ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  × Invalid `db.connectionString`: invalid port number. Expected a URL like `postgres://user:password@host:5432/database`.

  i The checks that need the database were skipped. Fix the connection settings, or pass --disable-db or set db.disableConnection to check without a database.

The language server shows the same message as a showMessage warning on every configuration load where the string is invalid. The message never repeats the connection string, since it may contain a password. With disableConnection: true the string is not reported.

Behavior change worth reviewing

execute_statement itself now checks allowStatementExecutionsAgainst. Before, only the code action was marked disabled, and a client calling pgls.executeStatement directly could execute against any database. A truncated result stops reading after 101 rows, but the server still sends the rest of the result, which sqlx drains before it reuses the connection.

Addresses #771 and #511

@psteinroe
psteinroe force-pushed the fix/execute-statement-results branch from 7ffd18b to 03d0003 Compare October 19, 2026 12:33
@psteinroe
psteinroe force-pushed the fix/execute-statement-results branch from 03d0003 to 54744f4 Compare October 20, 2026 07:36

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant