mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-16 04:28:11 +00:00
fix(lbug): bump @ladybugdb/core to 0.21.2 to stop doubled rows after delete and re-copy
LadybugDB 0.21.0 and 0.21.1 return every row of a table that spans more than one native vector twice once the incremental writeback has DETACH DELETEd it and a COPY into an earlier table has run. NodeGroup::scan let a morsel that ended before the group's first live row wrap an unsigned subtraction and rescan to the end of the group (LadybugDB #1085, fixed in 0.21.2). No primary key error fires. The identity guard from #3442 stops the run with "unexpected or duplicate ID", so a Swift edit that pulls every importer into the write set failed on repos with more than 2048 structs. Only unreleased main was affected: 1.6.12 ships 0.18.3. Pin 0.21.2 in package.json, update the six @ladybugdb/core entries in the lockfile, and move coreVersion in the vendored FTS manifest. The FTS extension stays at 0.21.0 because no v0.21.1 or v0.21.2 artifact is published; the pairing assertion and its unit tests pass. Add a regression to the delete-nodes-for-files suite: 2049 structs with CONTAINS edges are loaded, every file is deleted, the graph is loaded again, and each id and edge must appear exactly once. Verification (Linux, Node 22.18): - lbug-delete-nodes-for-files: 11/11 on 0.21.2. With the 0.21.1 native packages swapped in, the new test fails with 4098 rows instead of 2049. - Reporter recipe end to end on the built CLI: incremental analyze exits 0 with no duplicate ids on a Swift-heavy fixture and on a 70-file Python fixture, with and without FTS. On 0.21.1 the Swift fixture exits 1. - A 0.21.1-written database opens and reads under 0.21.2. - prettier, eslint and typecheck:tests are clean on the changed files. - The full lbug-db project had not finished when this was committed. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
9572e71127
commit
0cdc3dfe39
4 changed files with 105 additions and 26 deletions
48
gitnexus/package-lock.json
generated
48
gitnexus/package-lock.json
generated
|
|
@ -23,7 +23,7 @@
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "PolyForm-Noncommercial-1.0.0",
|
"license": "PolyForm-Noncommercial-1.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ladybugdb/core": "0.21.1",
|
"@ladybugdb/core": "0.21.2",
|
||||||
"@modelcontextprotocol/sdk": "^1.0.0",
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
||||||
"@scarf/scarf": "^1.4.0",
|
"@scarf/scarf": "^1.4.0",
|
||||||
"busboy": "^1.6.0",
|
"busboy": "^1.6.0",
|
||||||
|
|
@ -737,9 +737,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@ladybugdb/core": {
|
"node_modules/@ladybugdb/core": {
|
||||||
"version": "0.21.1",
|
"version": "0.21.2",
|
||||||
"resolved": "https://registry.npmjs.org/@ladybugdb/core/-/core-0.21.1.tgz",
|
"resolved": "https://registry.npmjs.org/@ladybugdb/core/-/core-0.21.2.tgz",
|
||||||
"integrity": "sha512-G0LWyn/dIqX9yHlyjpR12Rvou2o1dvCB9EkuzGa5ykCYbzur8EQhRUbi4fw3FlbckWvR6rK/tVbnFpBcRLwiHg==",
|
"integrity": "sha512-pnD1p5AaxEdmqJsLtF6bYuSmbe+pHzmaxDPNhROFOx+f7eE/AUPJFhW+rebMD6PQxK40B2NhqXbdsPCJ+FLuxg==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -748,17 +748,17 @@
|
||||||
"node-addon-api": "^6.0.0"
|
"node-addon-api": "^6.0.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@ladybugdb/core-darwin-arm64": "0.21.1",
|
"@ladybugdb/core-darwin-arm64": "0.21.2",
|
||||||
"@ladybugdb/core-darwin-x64": "0.21.1",
|
"@ladybugdb/core-darwin-x64": "0.21.2",
|
||||||
"@ladybugdb/core-linux-arm64": "0.21.1",
|
"@ladybugdb/core-linux-arm64": "0.21.2",
|
||||||
"@ladybugdb/core-linux-x64": "0.21.1",
|
"@ladybugdb/core-linux-x64": "0.21.2",
|
||||||
"@ladybugdb/core-win32-x64": "0.21.1"
|
"@ladybugdb/core-win32-x64": "0.21.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@ladybugdb/core-darwin-arm64": {
|
"node_modules/@ladybugdb/core-darwin-arm64": {
|
||||||
"version": "0.21.1",
|
"version": "0.21.2",
|
||||||
"resolved": "https://registry.npmjs.org/@ladybugdb/core-darwin-arm64/-/core-darwin-arm64-0.21.1.tgz",
|
"resolved": "https://registry.npmjs.org/@ladybugdb/core-darwin-arm64/-/core-darwin-arm64-0.21.2.tgz",
|
||||||
"integrity": "sha512-TEFYNqBdbIojf1t29p3esgRhMDm56lD5eK91dwWFZJTVWAZoGXn+yLKs0NUQgj3lW2ZquuRTLZGglPhFEsDL1Q==",
|
"integrity": "sha512-xJrPBfdh+i51SVuPlj0qgve2HQloCqPomMh01RHKpRKl/pmrwj7dU+wnK+PDVb1OCAq5MAjt8SOiChvY89Wfiw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
|
@ -769,9 +769,9 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@ladybugdb/core-darwin-x64": {
|
"node_modules/@ladybugdb/core-darwin-x64": {
|
||||||
"version": "0.21.1",
|
"version": "0.21.2",
|
||||||
"resolved": "https://registry.npmjs.org/@ladybugdb/core-darwin-x64/-/core-darwin-x64-0.21.1.tgz",
|
"resolved": "https://registry.npmjs.org/@ladybugdb/core-darwin-x64/-/core-darwin-x64-0.21.2.tgz",
|
||||||
"integrity": "sha512-w9p3oKrqeMOeWpX3xdCc/hQJHfrZtpB9We+Ir+0qyls68dSQoeXXR1GZYzzTElOtxr4OM5USwYbVyxADx+CMZg==",
|
"integrity": "sha512-zF+iONU8WOtzj9OLNr1CewQMcoJ+gwO3TJ0H4Lz+TA9D7JEdcTiHcdIQD4HQoJKEnKOwhL33MkWBdst8SfcV0g==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
|
@ -782,9 +782,9 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@ladybugdb/core-linux-arm64": {
|
"node_modules/@ladybugdb/core-linux-arm64": {
|
||||||
"version": "0.21.1",
|
"version": "0.21.2",
|
||||||
"resolved": "https://registry.npmjs.org/@ladybugdb/core-linux-arm64/-/core-linux-arm64-0.21.1.tgz",
|
"resolved": "https://registry.npmjs.org/@ladybugdb/core-linux-arm64/-/core-linux-arm64-0.21.2.tgz",
|
||||||
"integrity": "sha512-TodWmzOHxmmKvXXo9buBXGeyolxf/NqBUbo/LcR/tuMViKhGH8TBzIXi8DfVVwmsJ+CQCU065TvXgv2JoHAlZg==",
|
"integrity": "sha512-t/Z2ESuwx6RaEruZzGFrPHX19PEz5vKRVCm5fmSr85DqLd8/W5KWcw4f/RUpQtHdU2gdYLKkBur8yEpn36wNZA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
|
@ -795,9 +795,9 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@ladybugdb/core-linux-x64": {
|
"node_modules/@ladybugdb/core-linux-x64": {
|
||||||
"version": "0.21.1",
|
"version": "0.21.2",
|
||||||
"resolved": "https://registry.npmjs.org/@ladybugdb/core-linux-x64/-/core-linux-x64-0.21.1.tgz",
|
"resolved": "https://registry.npmjs.org/@ladybugdb/core-linux-x64/-/core-linux-x64-0.21.2.tgz",
|
||||||
"integrity": "sha512-hCcLYv8ds0x4fkTaRkuc4f75KLdH9e0EV51ne6uBNdQSY7kyc0RgSoUG3utUGfFDMMkfgIJAeIxQY4ck9jQiXg==",
|
"integrity": "sha512-U4cAfkmPjixDURzyrkYG9NTzjEJpitaTOOATGWLTl78coc3oLpIil71wN+y2e0UuM4yd7450iLTyzL2QFzUazg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
|
@ -808,9 +808,9 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@ladybugdb/core-win32-x64": {
|
"node_modules/@ladybugdb/core-win32-x64": {
|
||||||
"version": "0.21.1",
|
"version": "0.21.2",
|
||||||
"resolved": "https://registry.npmjs.org/@ladybugdb/core-win32-x64/-/core-win32-x64-0.21.1.tgz",
|
"resolved": "https://registry.npmjs.org/@ladybugdb/core-win32-x64/-/core-win32-x64-0.21.2.tgz",
|
||||||
"integrity": "sha512-nBS1XSRJfpexdlhkezmEiRtkUt2qEDp4zBjIhH+oxgRdD7UsRz1Jyit8foJuZAmUsoQGukN5LO+YeyDU2WZTyA==",
|
"integrity": "sha512-O4rQve2RcXPbEPv222N2OwM5p6TgWYeQ0vT+BlhBfo8cOxvFrXkI45gl6qbH5tKlBdGDLV2ijKyrb1hoAFx4Zg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@
|
||||||
"version": "node scripts/sync-plugin-manifests.mjs"
|
"version": "node scripts/sync-plugin-manifests.mjs"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ladybugdb/core": "0.21.1",
|
"@ladybugdb/core": "0.21.2",
|
||||||
"@modelcontextprotocol/sdk": "^1.0.0",
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
||||||
"@scarf/scarf": "^1.4.0",
|
"@scarf/scarf": "^1.4.0",
|
||||||
"busboy": "^1.6.0",
|
"busboy": "^1.6.0",
|
||||||
|
|
|
||||||
|
|
@ -566,3 +566,82 @@ withTestLbugDB('embedding-row-dml-vector-gate', (handle) => {
|
||||||
}, 120_000);
|
}, 120_000);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete-all-then-recopy of a table that spans more than one native vector.
|
||||||
|
*
|
||||||
|
* @ladybugdb/core 0.21.0 and 0.21.1 returned every row of such a table twice
|
||||||
|
* once the incremental writeback had DETACH DELETEd it and a COPY into an
|
||||||
|
* earlier table had run: `NodeGroup::scan` let a morsel that ended before the
|
||||||
|
* group's first live row wrap an unsigned subtraction and rescan to the end of
|
||||||
|
* the group (LadybugDB #1085, fixed in 0.21.2). No primary-key error fires, so
|
||||||
|
* the only symptom was `Graph identity reconciliation failed … duplicate ID`
|
||||||
|
* on repos with more than 2048 symbols of one label (Swift structs in the
|
||||||
|
* report that found it), and 2×-inflated counts for anything that scanned.
|
||||||
|
*
|
||||||
|
* The statement order below is the one `runFullAnalysisInner` issues: delete the
|
||||||
|
* write set's rows, then COPY File before the symbol tables.
|
||||||
|
*/
|
||||||
|
withTestLbugDB('delete-recopy-multi-vector-table', (handle) => {
|
||||||
|
describe('deleteNodesForFiles then loadGraphToLbug on a multi-vector table', () => {
|
||||||
|
// One native vector holds 2048 rows; 2049 is the smallest table that spans two.
|
||||||
|
const STRUCT_COUNT = 2049;
|
||||||
|
const STRUCTS_PER_FILE = 64;
|
||||||
|
const fileOf = (i: number): string => `Sources/S${Math.floor(i / STRUCTS_PER_FILE)}.swift`;
|
||||||
|
|
||||||
|
const buildStructGraph = () => {
|
||||||
|
const nodes: TestNodeInput[] = [];
|
||||||
|
const rels: TestRelInput[] = [];
|
||||||
|
const files = new Set<string>();
|
||||||
|
for (let i = 0; i < STRUCT_COUNT; i++) {
|
||||||
|
const fp = fileOf(i);
|
||||||
|
if (!files.has(fp)) {
|
||||||
|
files.add(fp);
|
||||||
|
nodes.push({ id: `File:${fp}`, label: 'File', name: path.basename(fp), filePath: fp });
|
||||||
|
}
|
||||||
|
const id = `Struct:${fp}:S${i}`;
|
||||||
|
nodes.push({
|
||||||
|
id,
|
||||||
|
label: 'Struct',
|
||||||
|
name: `S${i}`,
|
||||||
|
filePath: fp,
|
||||||
|
startLine: 1,
|
||||||
|
endLine: 3,
|
||||||
|
});
|
||||||
|
rels.push({ sourceId: `File:${fp}`, targetId: id, type: 'CONTAINS' });
|
||||||
|
}
|
||||||
|
return { graph: buildTestGraph(nodes, rels), filePaths: [...files] };
|
||||||
|
};
|
||||||
|
|
||||||
|
it('returns each struct and its edge exactly once after the rows were deleted and re-copied', async () => {
|
||||||
|
const { loadGraphToLbug, deleteNodesForFiles, executeQuery } =
|
||||||
|
await import('../../src/core/lbug/lbug-adapter.js');
|
||||||
|
const storagePath = path.dirname(handle.dbPath);
|
||||||
|
const structIds = async (): Promise<string[]> =>
|
||||||
|
((await executeQuery('MATCH (n:Struct) RETURN n.id AS id')) as Array<{ id: string }>).map(
|
||||||
|
(r) => String(r.id),
|
||||||
|
);
|
||||||
|
const containsEdges = async (): Promise<number> => {
|
||||||
|
const rows = (await executeQuery(
|
||||||
|
`MATCH (:File)-[r:CodeRelation]->(:Struct) WHERE r.type = 'CONTAINS' RETURN count(r) AS c`,
|
||||||
|
)) as Array<{ c: number | bigint }>;
|
||||||
|
return Number(rows[0]?.c ?? 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
const { graph, filePaths } = buildStructGraph();
|
||||||
|
await loadGraphToLbug(graph, '/tmp/repo', storagePath);
|
||||||
|
expect(new Set(await structIds()).size).toBe(STRUCT_COUNT);
|
||||||
|
|
||||||
|
// Every file is in the write set, as when a Swift edit pulls in all importers.
|
||||||
|
await deleteNodesForFiles(filePaths);
|
||||||
|
expect(await structIds()).toEqual([]);
|
||||||
|
|
||||||
|
await loadGraphToLbug(graph, '/tmp/repo', storagePath);
|
||||||
|
|
||||||
|
const ids = await structIds();
|
||||||
|
expect(ids).toHaveLength(STRUCT_COUNT);
|
||||||
|
expect(new Set(ids).size).toBe(STRUCT_COUNT);
|
||||||
|
expect(await containsEdges()).toBe(STRUCT_COUNT);
|
||||||
|
}, 120_000);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
||||||
2
gitnexus/vendor/lbug-fts/manifest.json
vendored
2
gitnexus/vendor/lbug-fts/manifest.json
vendored
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"coreVersion": "0.21.1",
|
"coreVersion": "0.21.2",
|
||||||
"extensionVersion": "0.21.0",
|
"extensionVersion": "0.21.0",
|
||||||
"filename": "libfts.lbug_extension",
|
"filename": "libfts.lbug_extension",
|
||||||
"officialRepo": "https://extension.ladybugdb.com/",
|
"officialRepo": "https://extension.ladybugdb.com/",
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue