Repository navigation
server: a Get that selects nothing reads the row, and nothing else - #9
Merged
Merged
Conversation
A Get with no select loaded every edge with a query of its own, reading the neighbour's key and nothing else, and so did the snapshot a recorder takes its images from. `Proto()` already answers an edge that is not a list from the column the row keeps it in, when nothing was loaded -- which is the whole of what such a Get answers for one. So each of those queries was spent on an answer the row already held, and the answer was worse for it: the neighbour read with its key alone, every other field of it at its zero value and its timestamps in the year 1, as though that were the row. `image()` has been trimming that back to the key ever since; the reference the column gives is that already. A list edge is still loaded: its keys are on the other table. What it cost, counted in Rove (lesomnus/rove#103), whose gate checks a reference by a Get through the layer below: an imported row sent 121 statements and sends 68, and a Get of a thing with four edges is one query where it was five. Its tests pass on SQLite and PostgreSQL with this generator. - An empty select answers an edge with its key and nothing else; it answered a tenant created in the year 1. - A Get of a seat, three edges, is one query; it was four. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KxtnpRW533bdErnW8QPhsk
This was referenced Oct 17, 2026
This was referenced Oct 17, 2026
lesomnus
added a commit
to lesomnus/roster
that referenced
this pull request
Oct 17, 2026
#130) protobuf-orm/protoc-gen-orm-ent#9: a Get with no select loaded every edge with a query of its own, to answer a key the row already holds, and answered a neighbour read with its key alone -- every other field at its zero value, timestamps in the year 1. So does the snapshot a recorder takes its images from. Both read the row and nothing else now: only `server/bare/` moves, the `q.With…` lines and the imports they used. Every reference a write names is checked with such a Get by the gate, so a write here pays one query less for each edge of each row it names. In rove, whose import this was found in, a Get of an asset went from five queries to one. Claude-Session: https://claude.ai/code/session_01KxtnpRW533bdErnW8QPhsk Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
lesomnus
added a commit
that referenced
this pull request
Oct 17, 2026
The pin was #9's head while it was open; it is master now, which has #9 and #8 beside it. Nothing it generates moved. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KxtnpRW533bdErnW8QPhsk
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.
A Get with no select loaded every edge with a query of its own that read the neighbour's key and nothing else, and so did the
snapshota recorder takes its images from. For an edge that is not a list,Proto()already answers from the column the row keeps the key in when nothing was loaded, and that key is all such a Get answers for an edge. So each of those queries was spent on something the row already held.The answer was also worse for it. The neighbour was read with its key alone, so every other field came back at its zero value, timestamps in the year 1, as though that were the row.
image()has been trimming that back to the key; the reference built from the column is already just the key.List edges are still loaded, because their keys are on the other table.
What it cost
Counted in Rove (lesomnus/rove#103). Its gate checks each reference with a Get through the layer below, so every write paid this once per edge of every row it referred to:
Rove's whole suite passes with this generator on SQLite, and
server/...passes on PostgreSQL. Its regenerated diff only removes theq.With…lines and the imports they used.Tests
TestGet/empty select answers an edge with its key and nothing else: before this change the reference came back as a tenant created in the year 1.TestAGetThatSelectsNothingIsOneQuery: a Get of a seat, which has three edges, takes one query; before this change it took four.Both fail on
mainwithout the change. CI's steps run clean locally:buf generatetwice,go generateininternal/apptest, then the root,runtimeandinternal/apptestsuites, the last on PostgreSQL as well.🤖 Generated with Claude Code
https://claude.ai/code/session_01KxtnpRW533bdErnW8QPhsk