kriszyp / lmdb-js

Simple, efficient, ultra-fast, scalable data store wrapper for LMDB
Other
484 stars 39 forks source link

False-positives in complex range query #79

Closed vladar closed 2 years ago

vladar commented 2 years ago

Faced with an issue with range queries. And it actually works the same in 1.5.5, so not sure - maybe this is expected behavior and I am missing something about ranges.

Here is a repro:

const { open } = require("lmdb-store")

const db = open({
  name: `store`,
  path: process.cwd() + `/test`,
})

const undefinedSymbol = Symbol(`undef`)

const keys = [
  [ 'prefix', `foo`, `foo`, `foo`, 1 ],
  [ 'prefix', `foo`, undefinedSymbol, `bar`, 2 ],
  [ 'prefix', `foo`, `baz`, undefinedSymbol, 3 ],
]

async function run() {
  db.transactionSync(() => {
    db.clear()
  })

  let promise
  keys.forEach((key, i) => {
    promise = db.put(key, i)
  })
  await promise

  const result = db.getRange({
    start: [ 'prefix', `foo`, [ undefinedSymbol, `ÿÿÿÿ` ], [ undefinedSymbol, `ÿÿÿÿ` ] ],
    end: [ 'prefix', `foo`, `ÿÿÿÿ`, `ÿÿÿÿ` ],
  })

  // Result is expected to include only values without `undefined`, i.e. [ 'prefix', `foo`, `foo`, `foo`, 1 ]
  // But actually includes also [ 'prefix', `foo`, `baz`, undefinedSymbol, 3 ]
  console.log(Array.from(result))
}

run().catch(console.error)

The idea is to get only values without undefined at the 2nd and 3rd elements of the index. So expected output:

[
  { key: [ 'prefix', 'foo', 'foo', 'foo', 1 ], value: 0 }
]

But the actual output is:

[
  { key: [ 'prefix', 'foo', 'baz', Symbol(undef), 3 ], value: 2 },
  { key: [ 'prefix', 'foo', 'foo', 'foo', 1 ], value: 0 }
]
vladar commented 2 years ago

Oh, ignore me, the result is actually correct for this range...