You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
perf(migration): qualify the ORDER BY so the notification copies use their index #1124
nostream-storage's scan_batch (used by nostream-cli migrate pg-to-lmdb) builds
SELECT {columns} FROM {table} [WHERE key > $1] ORDER BY key LIMIT $2
For notification_outbox and notification_delivery_log the column list is OUTBOX_COLUMNS / DELIVERY_LOG_COLUMNS, which begin id::text AS id. In PostgreSQL an ORDER BY name resolves to the output column first, so ORDER BY id sorts the text expression, not the uuid column. The indexes cover the uuid column, so each batch reads the remaining rows and sorts their text ids before applying LIMIT.
Correctness is unaffected: canonical uuid text has fixed dash positions, so lexicographic text order on lowercase hex agrees with PostgreSQL's byte-wise uuid order, and the keyset predicate (id > $1::uuid) stays consistent with the sort. The cost is the repeated sort, paid while the relay is stopped.
Acceptance
ORDER BY and the keyset predicate name the table (ORDER BY notification_outbox.id, notification_outbox.id > $1::uuid), so the plan can walk the uuid index and stop after LIMIT rows instead of sorting each batch.
Verify with EXPLAIN on both notification tables before and after: before shows a Sort above the scan; after, an index scan with no sort node. A test can assert the generated SQL names the table in both clauses, but the plan is the evidence.
Where it came from
Static review round 18 on factory/029-pg-to-lmdb (finding P2, non-blocking). The branch is frozen for review, so it was not fixed there.
I've gone through the issue and the notes on field-by-field parity.
I can take this on:
Hoist the base users column list into postgres/users.rs as a single shared constant.
Update postgres/migration.rs to reuse this base list and append , tos_accepted_at, keeping the exact column ordering intact so field-by-field parity is preserved without drift.
Ensure the parity target (cargo test -p nostream-storage --features postgres --test parity -- --ignored) and CI checks pass cleanly.
I've put together the fix for #1124 on a fresh branch off rewrite/main.
In migration.rs, I updated Cursor::Uuid to qualify the table name in both the WHERE condition ({table_name}.id > $1::uuid) and ORDER BY (ORDER BY {table_name}.id). This ensures Postgres uses the underlying UUID index directly instead of sorting on the id::text alias. I also updated the unit test and added the changeset.
Activity
tirthraj01 commentedon Nov 14, 2026
Hi @chappie-daemon @cameri,
I've gone through the issue and the notes on field-by-field parity.
I can take this on:
userscolumn list intopostgres/users.rsas a single shared constant.postgres/migration.rsto reuse this base list and append, tos_accepted_at, keeping the exact column ordering intact so field-by-field parity is preserved without drift.cargo test -p nostream-storage --features postgres --test parity -- --ignored) and CI checks pass cleanly.Could you please assign this issue to me?
cameri commentedon Nov 14, 2026
@tirthraj01 Assigned to you.
tirthraj01 commentedon Nov 15, 2026
Hi @cameri, @chappie-daemon,
I've put together the fix for #1124 on a fresh branch off
rewrite/main.In
migration.rs, I updatedCursor::Uuidto qualify the table name in both theWHEREcondition ({table_name}.id > $1::uuid) andORDER BY(ORDER BY {table_name}.id). This ensures Postgres uses the underlying UUID index directly instead of sorting on theid::textalias. I also updated the unit test and added the changeset.Because of the repo's interaction limits on external PRs, here is the branch on my fork:
rewrite/main...tirthraj01:nostream:perf/1124-qualify-notification-order-by
Let me know if this looks good or if you'd like me to tweak anything!