HarperFast / HarperFast/harper

search() plain-object shorthand silently does a full-table scan instead of filtering

Open
#1,426 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

The resource `search()` API accepts a plain object literal — `tables.Widget.search({ bucket: 'b1' })` — but **silently ignores it as a filter and returns an unconditional full-table scan** instead of filtering by the attribute. The correct indexed form is the array-of-conditions shorthand: `search([{ attribute: 'bucket', value: 'b1' }])`.

The plain-object form neither errors nor warns, so a developer expecting a filtered result gets the entire table back — a silent-wrong result plus a hidden full scan on large tables.

## Reproduction

```js
// Expected: only rows where bucket === 'b1'
const wrong = await tables.Widget.search({ bucket: 'b1' }); // returns ALL rows (full scan)

// Correct: array of condition objects
const right = await tables.Widget.search([{ attribute: 'bucket', value: 'b1' }]); // filtered
```

`search()` with the object form returns every row; the `bucket` key is neither applied as a predicate nor rejected.

## Impact

Low–medium. Two failure modes from one call:
- **Silent-wrong result** — the caller believes it filtered, but receives the whole table.
- **Performance footgun** — a full-table scan where an indexed lookup was intended; bites hardest on large tables.

Surfaced incidentally during the QA campaign (QA-184): probe code using the object shorthand was inadvertently full-scanning.

## Suggested fix

Either:
1. **DWIM** — accept the plain-object form as an equality filter (`{attr: val}` → `[{attribute: attr, value: val}]`), or
2. **Fail loud** — reject the object form with a clear error pointing at the array-condition form.

At minimum, document the two forms and that the object form is not a filter.

---
*Surfaced by the QA-explorer exploratory campaign. Filed by Claude (Opus 4.8).*

Contributor guide

Open the contributing guide

Research direction

Start at the tables.Widget.search() entry point and trace how plain objects differ from array-of-condition inputs. Reproduce the full-table result, then inspect the existing search behavior and tests before choosing whether object input becomes an equality filter or produces an explanatory error. Done means the silent full scan is eliminated and the documented array-condition form remains correct.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.