HarperFast / HarperFast/harper

Interrupted drop reloads the table when the catalog has a named primary-key row

Open
#2,300 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
89
Forks
10
Avg merge
2d 6h
Merged PRs (30d)
200

Description

## Summary

`dropTable()` always writes its drop tombstone to the table's **bare** catalog row (`/`), but the startup interrupted-drop reconcile in `initStores` reads `dropping` off `tableDef.primary` — which is the **named primary-key row** (`/`) whenever the catalog has one. On a catalog of that shape the tombstone is invisible to the reconcile, so an interrupted drop reloads the table instead of completing the drop.

Found by code reading while reviewing #2296; not caused by it, and present unchanged on `main`.

## Mechanism

`resources/Table.ts` — `dropTable()` tombstones one fixed key:

```js
const primaryCatalogKey = TableResource.tableName + '/';
const primaryMeta = (dbisDb as any).getSync(primaryCatalogKey);
```

`resources/databases.ts` — the catalog scan lets a named primary-key row win, then the reconcile reads only that row:

```js
if (attribute_name == null || value.isPrimaryKey) tableDef.primary = value; // named row assigned last
...
if (!tableDef.primary?.dropping) { // never true for the named row
clearInterruptedDropEntries(path, tableName);
continue;
}
```

The same asymmetry is why the descriptor write in #2296's branch has to check both rows (`tableIsDropping`); this is the load-side half, which that PR deliberately leaves alone.

## Impact

A table whose drop was interrupted (process death or a column-family drop failure partway through) comes back on the next load, with its catalog rows and column families intact, and nothing is logged — the drop simply looks like it never happened. Bounded to catalogs that carry a named primary-key row, which is the pre-5.x shape rather than the one `table()` writes today.

## Suggested fix

Track the bare row separately during the catalog scan and treat either row's `dropping` flag as a tombstone, taking `dropGeneration` from whichever row carries it. `unitTests/resources/dropTableGhost.test.js` is the suite this belongs in; it currently only builds modern-shaped catalogs.

Contributor guide

Open the contributing guide

Research direction

Read resources/Table.ts and resources/databases.ts to trace how drop tombstones are written and reconciled, then inspect unitTests/resources/dropTableGhost.test.js. Add coverage for a catalog with a named primary-key row and verify that an interrupted drop is detected and completed on startup, including the drop generation from the relevant row.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
databases
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.