Repository navigation
Conversation
pgls_analyser::walk_statements is the only loop that follows the catalog and the session through a file: sections, unparsable statements, function bodies and identifier parameters are handled once. The analyser runs its rules in it, and the workspace resolves hover, completions, inlay hints, semantic tokens and code actions in it. The catalog that a statement at the end of the walk sees is the one of its section, so completions in the first statement after a down section no longer see its changes. Statements share their parse trees with the workspace's cache instead of copying them.
… parameters A statement whose names are psql variables still takes its locks and changes the transaction, so the walk applies it to the session and only taints the catalog. The rules spec harness converts psql variables like the workspace does, and three specs check that the lock rules see such statements.
This was referenced Oct 26, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #997. Part of the rebuild described in #997 (point 3: one walk). Replaces #974 and #965.
The analyser and the workspace each had a loop that follows the catalog through the statements of a file:
Analyser::analysefor lint and typecheck, andWorkspaceServer::walk_statementsfor hover, completions, inlay hints, semantic tokens and the expand-*action. They handled migration sections, statements that don't parse and identifier parameters each in their own way, and they differed.What was broken
The workspace's loop only switched to a new migration section when it reached a statement in it. Completions walk up to the start of the statement being completed, so in the first statement after a down section they saw the down section's changes, while lint didn't:
Statements with identifier parameters were handled differently too: the analyser applied
create table :name (...)to the catalog with the placeholder name, so the file then had a tablename; the workspace tainted the catalog instead.What changed
pgls_analyser::walk_statements(WalkParams, visit)inwalk.rsis the only walk. It holds the section handling (each section has its own session and transaction mode, a down section's changes are dropped afterwards, and the implicit transaction blocks of feat(analyser): report statements that can't run in a transaction block #940), unparsable statements tainting the catalog, function bodies not being applied, and identifier parameters.visitgets each statement with itsAnalysedFileContext.WalkParams::endstops the walk, and the walk returns the catalog that a statement atendsees: the section that containsenddecides which one, not the last statement walked. That fixes the completions case above.best_effortturns onCatalog::best_effortfor the editor features (feat(catalog): keep editor features working after DO, CALL and unparsable statements; resolve CALL #914).Analyser::analyseruns the rules invisit.WorkspaceServer::walk_statementscollects the statements that start beforeendand calls the same function; its visitors skip statements with identifier parameters, like before.ALTER TABLE authors ADD COLUMN :"column" TEXTtakes itsACCESS EXCLUSIVElock, andCREATE TABLE t (:"c" text)createstin the transaction, for the lock rules. The analyser still turns typecheck off for the rest of the file after one, since a tainted catalog can still have wrong column types. Hover, completions and inlay hints keep working on the tainted catalog.may_change_catalogandis_plain_querymoved intowalk.rsand are private to the crate now.AnalysableStatement::rootis anArc<NodeEnum>(AnalysableStatement::newstill takes an owned tree),AnalysedFileContext::stmtsis&[&NodeEnum], the workspace cachesResult<Arc<NodeEnum>, SyntaxDiagnostic>, and the formatter copies a tree withArc::make_mutonly when it puts a formatted body into it. Before, every analysis copied each tree twice, and every hover or inlay hint request copied every statement before the cursor.Tests
runningStatementWhileHoldingAccessExclusive,avoidWideLockWindowandlockTimeoutWarningafter statements with a psql variable as a column name: the lock is held, and a table created with such a column doesn't need a lock timeout. The rules spec harness now converts psql variables like the workspace does, otherwise these statements don't parse. They fail if the walk skips the session for such statements, which fix(workspace): build the catalog the same way for lint, hover, completions and inlay hints #974 did.lint_hover_and_completions_see_the_same_catalog(workspace) checks typecheck diagnostics, completions and hover in the same file for three cases: the first statement after a down section, a statement after one that doesn't parse, and a statement aftercreate table :tbl.pgls_analyser(rules specs, Postgres regression; the snapshots don't change),pgls_workspaceandpgls_lsppass, and clippy on the whole workspace.Cost
The same walk as before for each request: O(statements before the end of the request). The workspace now collects the statements before walking them, which costs a
Vecof them. Caching the walk follows later in the stack.