Repository navigation
Conversation
One line per object of the materialized snapshot, in its order, so that a change of how it is built shows any difference in ids, order or fields.
Catalog::snapshot() searched all tables and kept all columns but those of the table for each relation the file defines, searched all types for each column type and file type, and went over the snapshot's objects again for each dropped relation, type and function. A file with 5,000 tables took 630 ms per snapshot, which hover builds after each change before the hovered statement. The builder now indexes the tables, types and sequences by name once, drops the dropped objects in one pass per kind, and replaces the columns of all defined tables in one pass. The objects, their ids and their order are the same, see snapshot_of_a_file_with_many_changes.
The ids of the file's objects follow the iteration order of a hash map, which differs between x86_64 and aarch64. The test writes them as the table or type they stand for and sorts the lines. Recorded again with the builder from before the previous commit, and unchanged with it.
With the features of the whole workspace, serde_json keeps the order of the struct fields instead of sorting the keys.
psteinroe
changed the base branch from
main
to
perf/editor-requests-cancellable
October 26, 2026 19:55
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.
Catalog::snapshot()builds theSnapshotthat hover and completions read: the database snapshot with the file's changes. Its builder was quadratic in the size of the file. For each relation the file defines, it searched all tables, removed that table's columns with a pass over all columns, and looked up each column's type with a pass over all types. Each dropped relation, type and function cost another pass over the objects of its kind, and each file type was checked against all types.With #982, hover after an edit above the hovered statement was dominated by this. In a 20,000-statement migration file (5,000 tables), one snapshot took 630 ms of the 744 ms per keystroke.
What changed
materialize.rsonly. It produces the same objects, ids and order as before on the same platform:type_idanddefine_typestill see the types defined before them.define_relationonly finds or adds the table.define_columnsthen takes out the old columns of all defined tables in one pass over the columns, and appends the new ones in the order of the relations, as before.Test
The first commit adds
snapshot_of_a_file_with_many_changesand records it with the old builder. The input file:The test renders every schema, table, column, type, function, index and sequence of the snapshot as one JSON line. The second commit doesn't change the recorded output.
The file's objects get their ids in the iteration order of the catalog's hash maps. That order differs between x86_64 and aarch64, so the first version of the test failed on the macOS runner. The third commit writes each id as the table or type it stands for, and sorts the lines. The fourth sorts the JSON keys, since
cargo test --workspaceturns on serde_json'spreserve_order. I recorded it again with the old builder, and the new builder gives the same output. On x86_64, the order-sensitive rendering from the first commit was also identical between the old and the new builder. The otherpgls_catalog,pgls_hoverandpgls_completionstests pass.Numbers
Release build, on top of #982 (this PR doesn't depend on that stack and is based on
main). The scenarios are the ones from #982: a dbmate file of tables, indexes, SQL functions and queries, one keystroke in a name, averages over 20 keystrokes. #982 → #982 with this PR:CREATE TABLE3 statements aboveInlay hints don't build a snapshot and are unchanged within noise. Completions after an edit above them build one too, but their time is mostly
pgls_completions::completegoing over the 5,000 file tables of the snapshot, so they stay about the same.