fix(import): use UPSERT for specs to handle duplicate record IDs#15
Merged
CamonZ merged 2 commits intoCamonZ:masterfrom Feb 19, 2026
Merged
fix(import): use UPSERT for specs to handle duplicate record IDs#15CamonZ merged 2 commits intoCamonZ:masterfrom
CamonZ merged 2 commits intoCamonZ:masterfrom
Conversation
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.
Problem
Import can fail when
ex_astextracts both a@callbackand a@specfor the same function (same module, name, arity), because both entries can produceclause_index = 0.That generates the same SurrealDB record ID twice:
specs:[module_name, function_name, arity, clause_index]So the second write fails with:
Database record ... already exists.Example
In
MyApp.Integrations.UrlShortener:Both extracted entries map to:
specs:['MyApp.Integrations.UrlShortener', 'shorten', 3, 0]With
CREATE, the second insert errors.Root Cause
import_specsused:CREATE specs:[$module_name, $function_name, $arity, $clause_index] SET ...CREATEis not idempotent for duplicate natural keys, even when duplicate rows are valid extraction output (@callback+@spec).Fix
Switched
CREATEtoUPSERTinimport_specs(db/src/queries/import.rs):UPSERT specs:[$module_name, $function_name, $arity, $clause_index] SET ...This makes duplicate keys safe: the later row updates the same record instead of failing import.
Why This Is Safe
module + function + arity + clause_index).Validation
Added regression test:
test_import_specs_upserts_duplicate_record_idsindb/src/queries/import.rsThe test verifies:
Executed:
cargo test -p db import_specs(pass)