feat(datastore): add Maven remote version size_bytes writer
What
Adds MavenRemoteVersionStore.AddMavenRemoteVersionSizeBytes, the Maven twin of npm's AddNpmRemoteVersionSizeBytes: a delta-based writer for maven_remote_versions.size_bytes (UPDATE ... SET size_bytes = GREATEST(size_bytes + delta, 0), soft_deleted_at IS NULL filter, zero-delta short-circuit, identifier-free error wrap).
Why
Step 3 of the Maven version size accounting plan (issue #550 (closed)). The column and index exist with zero writers; this ships the writer. The first caller is the S14 Track B cache-fill step, recorded as a dependency in the plan — until it lands, the mirrored test suite is the only exerciser, npm-parity style.
Notes for reviewers
- Mirrored subtest-for-subtest from the npm twin suite (guards, zero-delta, clamp, transient-error wrap, live delta round-trip, soft-delete/missing/cross-namespace no-ops).
- One deliberate, plan-documented divergence from the npm twin: the error wrap is identifier-free per
docs/dev/database-query-patterns.md; the future caller logsnamespace_id/version_idas its own structured fields. - Also touches:
query_names.go(query-name constant for the new statement),maven_remote_cache.go(comment-honesty edit — the old text claimed no store existed),npm_remote_write_test.go(measured//nolint:dupljustification for the zero-delta twins), and the plan file. - Validated with
/validate-step(ADVISORIES ONLY; advisories resolved in-branch).
Related to #550 (closed)
Database Review Evidence
Queries
Note
Plans are from EXPLAIN (ANALYZE, BUFFERS) against an ephemeral
PostgreSQL 17 container (matching GL_PG_CURR_VERSION from
.gitlab-ci-other-versions.yml), with synthesized seed data rolled
back per query and the container torn down at the end of the run.
Numbers reflect moderate cardinality and do not capture
production-scale effects. See
Database review evidence
for seed sizing, methodology, and the anomalies the skill flags.
Expand each row's details for the seed shape, rendered SQL, bound args,
and raw plan.
| Method | Plan node | Index | Rows (plan / actual) | Cost | Time | Buffers (hit / read) | Partitions |
|---|---|---|---|---|---|---|---|
datastore.AddMavenRemoteVersionSizeBytes |
Update | n/a | 1 / 1 | 0.00..1.75 | 1.042ms | 24 / 2 | 1/64 |
datastore.AddMavenRemoteVersionSizeBytes
Summary: Point UPDATE on maven_remote_versions keyed by
namespace + version id, exactly matching the method's intent (a
buffered-counter delta write). The namespace_id partition key is bound,
so the planner prunes to a single partition (1 of 64, p37 at seed) and
the FK-constraint trigger checks add trivial overhead. At the recipe's
50-row seed the planner correctly picks a Seq Scan over the whole tiny
partition — the pk_maven_remote_versions (id, namespace_id) index
loses on cost at this cardinality and is not flagged; at production
partition sizes the index serves the id predicate. No anomalies.
Seed shape: namespaces=1, repositories=1, maven_remote_repositories=1, maven_remote_packages=1, maven_remote_versions=50 (49 siblings share the
target's namespace partition)
Rendered SQL:
UPDATE public.maven_remote_versions
SET size_bytes = GREATEST(maven_remote_versions.size_bytes + $1, $2)
WHERE ((maven_remote_versions.namespace_id = $3::uuid) AND (maven_remote_versions.id = $4::uuid)) AND (maven_remote_versions.soft_deleted_at IS NULL)Bound args: [5, 0, e4a050c1-e1e6-4fb4-b522-425a213a2446, a75141ae-9e05-4d43-bb88-83d0bd337da9]
Plan (EXPLAIN (ANALYZE, BUFFERS) output):
Update on maven_remote_versions (cost=0.00..1.75 rows=0 width=0) (actual time=0.147..0.148 rows=0 loops=1)
Update on maven_remote_versions_p37 maven_remote_versions_1
Buffers: shared hit=24 read=2
-> Seq Scan on maven_remote_versions_p37 maven_remote_versions_1 (cost=0.00..1.75 rows=1 width=18) (actual time=0.005..0.007 rows=1 loops=1)
Filter: ((soft_deleted_at IS NULL) AND (namespace_id = 'e4a050c1-e1e6-4fb4-b522-425a213a2446'::uuid) AND (id = 'a75141ae-9e05-4d43-bb88-83d0bd337da9'::uuid))
Rows Removed by Filter: 49
Buffers: shared hit=1
Planning:
Buffers: shared hit=433
Planning Time: 0.783 ms
Trigger for constraint fk_maven_remote_versions_maven_remote_package_id on maven_remote_versions_p37: time=0.590 calls=1
Trigger for constraint fk_maven_remote_versions_namespace_id_namespaces on maven_remote_versions_p37: time=0.202 calls=1
Execution Time: 1.042 msTimings: planning 0.783ms, execution 1.042ms, total 1.825ms.