Skip to content

Ported back to original Go version#20

Merged
radim merged 42 commits into
masterfrom
go-version
May 15, 2026
Merged

Ported back to original Go version#20
radim merged 42 commits into
masterfrom
go-version

Conversation

@radim
Copy link
Copy Markdown
Member

@radim radim commented May 15, 2026

It's complicated..

radim and others added 30 commits May 15, 2026 20:19
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
JSON omits both when nil and round-trips when set. content_hash
flips whenever either field changes so DDL-shifting ALTERs produce
a fresh snapshot, while pure stats writes stay stable.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirror the production file naming after refactor e0a58d5:

- server_test.go         — setupOfflineTest helpers + getSchema contract
- helpers_test.go        — filterSnap, injectMeta, metaJSONResult
- handlers_schema_test.go    — list/describe/search/find_related
- handlers_query_test.go     — validate/explain/check_migration/suggest
- handlers_lint_test.go      — lint_schema scopes and filters
- handlers_health_test.go    — compare_nodes/detect*/vacuum_health
- handlers_snapshot_test.go  — reload_schema candidate handling

Add tools_registration_test.go: round-trips the registered tool list
through ListTools and asserts every listed tool resolves to a handler.
Catches drift between tools.go (registration) and handlers_*.go
(implementations). Also pins the offline tool surface — online-only
tools (explain_query, refresh_schema, check_drift) must not appear
without a live pool.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
9 tests for SnapshotStore: Put insert/dedup/key-scoping, Get across
all three SnapshotRef variants plus not-found sentinel, List with
half-open TimeRange, DeleteBefore retention, Latest on empty key.
8 tests for config: ProjectID precedence and basename fallback,
CLI-override invariants, per-profile database_id round-trip, missing
profile error, demo fixture parses.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Walks each rung of the precedence ladder (--db > --schema > --profile >
[default].profile > single-profile fallback) at the resolver layer, plus
on-disk CLI tests that exercise requireDB and resolveSnapshotKey through
a real dryrun.toml.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Seeds two streams / three snapshots through history.Open, runs export,
walks the output tree and asserts each .json.zst decompresses back to a
SchemaSnapshot whose ContentHash matches the filename. Adds ListKeys
coverage for distinct-key ordering and the legacy NULL-keyed skip.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ariants

JSON round-trip for the PlannerStatsSnapshot / ActivityStatsSnapshot shapes
(plus QualifiedName), content_hash sensitivity across add/remove column,
add/remove index, PK move, FK add, RLS toggle, and the schema_ref_hash
binding planner/activity to a fresh schema content_hash. History store
coverage for PutPlanner idempotency on (schema_ref, content_hash),
PutActivity append-only semantics, LatestPlanner ordering, LatestActivity
per-node collapse, and GetPlanner/GetActivity schema_ref scoping. Live-DB
capture tests gated on TEST_DATABASE_URL since the repo carries no
testcontainers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…s paths

bloat, summarize, and vacuum tests rebuilt around AnnotatedSchema fixtures
(planner sizing + merged activity) so DetectUnusedIndexes, DetectBloatedIndexes,
EstimateIndexBloat and AnalyzeVacuumHealth get coverage in the new shape.
advise tests in query/ migrate to *AnnotatedSchema via a small fixture helper;
perNodeBreakdown now drives off MergedActivity.

audit indexes/bloated and vacuum/large_table_defaults tests removed since
those rules are stubs without AnnotatedSchema; equivalent coverage lives in
schema/summarize_test.go. SuggestedVacuumKnobs keeps a standalone sanity check.

mcp/helpers_test loses the NodeStats branch of filterSnap. schema/clone_test
is deleted along with CloneForStats. schema/hash_test drops the stats-only
stability case (impossible by construction now). query/validate_test skips
the unbounded-query assertion until ValidateQuery accepts AnnotatedSchema.

Tests that used inline TableStats / IndexStats / NodeStats literals are
purged; migration_test / validate_test fixtures stripped of those fields.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lock down the three init.go branches with a stub Capturer/Writer so
future changes can't silently re-enable schema capture on a standby
or drop the planner stream on a primary. Adds a companion MCP test
ensuring reload_schema prefers history.db over a stray schema.json —
otherwise stats apply loses its planner/activity binding.
The tool() shorthand returned a bare mcp.Tool with no parameter
declarations, serializing as {"properties":{},"required":[],"type":""}.
Clients couldn't validate args or render parameter UIs.

Replace eight call sites with mcp.NewTool(...) declaring real schemas:
find_related, validate_query, check_migration, suggest_index,
compare_nodes get their required/optional params; reload_schema,
refresh_schema, check_drift declare empty object schemas.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Iterate the registered tool list and assert inputSchema.type == "object"
on each. Pin the required-args contract for tools that have any so
future helper changes that drop required markers fail loudly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
radim and others added 11 commits May 15, 2026 20:19
- advise: offline produces JSON wrapper with validation + offline hint;
  include_index_suggestions=false omits the key; malformed SQL surfaces
  a parse error instead of panicking.
- analyze_plan: accepts both {"Plan":...} and [{"Plan":...}] shapes;
  missing or malformed plan_json returns a typed error.
- schema_diff: graceful error path when neither history store nor live
  DB is available; handler is reachable through the MCP client.

Also refreshes tools_registration_test fixtures for the new surface
(advise, analyze_plan, schema_diff added; suggest_index removed) and
the DetectPlanWarnings export rename.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drive runSnapshotActivity across primary-refused, standby-without-
snapshot-refused, standby-binds-to-stored-hash, and --allow-orphan
unbound-row cases.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…eams

New store_kind_aware_test.go drives StoredSnapshot of each variant through
Put -> Get -> List, asserts ListKinds returns the populated subset (with
activity entries fanning out per node_source), and pins that Latest /
DeleteBefore isolate per kind so V3's per-kind sync diff and retention
loops can't bleed across streams.

Existing tests in snapshot_store_test.go, store_test.go, stats_test.go,
and the cmd/mcp stubs were retargeted at the schema-specific wrappers
(PutSchema / GetSchema / ...) so coverage of the v0.6 surface stays
intact through the interface widening.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Eight tests pin the bundle contract:

- Round-trip schema/planner/activity through Put -> Get -> List.
- Bundle JSON shape: top-level {schema, planner, activity} with planner
  null when absent and activity keyed by node_source. Asserted at the
  raw-JSON level so a Go struct rename can't silently break Rust compat.
- Schema dedup: byte-identical re-put returns PutDeduped, dir holds one
  bundle file.
- Orphan: putting planner / activity without a matching schema bundle
  errors out (ErrOrphanSnapshot).
- Activity by node: two node_source puts populate bundle.activity as a
  two-entry map inside a single bundle, not as separate files.
- Concurrent put idempotency: 16 goroutines racing the same schema land
  exactly one bundle and zero .bundle-*.tmp leftovers.
- Planner / activity dedup compares against the existing slot and skips
  the bundle rewrite (verified by mtime equality).
- ListKeys ignores empty (project, database) directories left behind by
  an aborted write.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Seven tests pin the diff-by-content-hash sync loop and the cross-store
wire format:

- Empty dst gets every row Copied, zero UpToDate.
- Pre-seeded dst reports UpToDate for matching hashes and Copied for
  the rest; dst ends up holding both.
- Multi-node activity copies each node_source as its own row, no
  collisions, label preserved through List -> Get -> Put.
- Kind order is schema -> planner -> activity, verified by pushing
  into a FilesystemStore dst (which enforces the orphan rule).
- --all routes through src.ListKeys and surfaces every key in the
  output block.
- The acceptance round trip: SQLite -> FilesystemStore -> fresh SQLite,
  asserting content_hashes match per kind. If the bundle JSON layout
  ever drifts between encoder and decoder, this loses symmetry first.
- Empty-key sync prints a human notice, not an empty buffer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@radim radim merged commit 5efe060 into master May 15, 2026
@radim radim deleted the go-version branch May 15, 2026 18:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant