fix(ext/kv): reverse mapping between AnyValue::Bool and KeyPart::Bool (#18365)

Previously the mapping between `AnyValue::Bool` and `KeyPart::Bool` was
inverted.

This patch also allows using the empty key `[]` as range start/end to
`snapshot_read`.
This commit is contained in:
Heyang Zhou 2023-03-23 04:53:16 +08:00 committed by GitHub
parent a117d3d91e
commit 533e33131f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 20 deletions

View File

@ -600,6 +600,14 @@ dbTest("list prefix with end empty", async (db) => {
assertEquals(entries.length, 0);
});
dbTest("list prefix with empty prefix", async (db) => {
await db.set(["a"], 1);
const entries = await collect(db.list({ prefix: [] }));
assertEquals(entries, [
{ key: ["a"], value: 1, versionstamp: "00000000000000010000" },
]);
});
dbTest("list prefix reverse", async (db) => {
await setupData(db);
@ -966,3 +974,23 @@ dbTest("invalid mutation type rejects", async (db) => {
.commit();
}, TypeError);
});
dbTest("key ordering", async (db) => {
await db.atomic()
.set([new Uint8Array(0x1)], 0)
.set(["a"], 0)
.set([1n], 0)
.set([3.14], 0)
.set([false], 0)
.set([true], 0)
.commit();
assertEquals((await collect(db.list({ prefix: [] }))).map((x) => x.key), [
[new Uint8Array(0x1)],
["a"],
[1n],
[3.14],
[false],
[true],
]);
});

View File

@ -34,14 +34,6 @@ pub fn canonicalize_f64(n: f64) -> f64 {
}
pub fn encode_key(key: &Key) -> std::io::Result<Vec<u8>> {
// Disallow empty key
if key.0.is_empty() {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"key should not be empty",
));
}
let mut output: Vec<u8> = vec![];
for part in &key.0 {
match part {
@ -73,14 +65,6 @@ pub fn encode_key(key: &Key) -> std::io::Result<Vec<u8>> {
}
pub fn decode_key(mut bytes: &[u8]) -> std::io::Result<Key> {
// Disallow empty key
if bytes.is_empty() {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"key should not be empty",
));
}
let mut key = Key(vec![]);
while !bytes.is_empty() {
let tag = bytes[0];

View File

@ -102,8 +102,8 @@ type KvKey = Vec<AnyValue>;
impl From<AnyValue> for KeyPart {
fn from(value: AnyValue) -> Self {
match value {
AnyValue::Bool(false) => KeyPart::True,
AnyValue::Bool(true) => KeyPart::False,
AnyValue::Bool(false) => KeyPart::False,
AnyValue::Bool(true) => KeyPart::True,
AnyValue::Number(n) => KeyPart::Float(n),
AnyValue::BigInt(n) => KeyPart::Int(n),
AnyValue::String(s) => KeyPart::String(s),
@ -115,8 +115,8 @@ impl From<AnyValue> for KeyPart {
impl From<KeyPart> for AnyValue {
fn from(value: KeyPart) -> Self {
match value {
KeyPart::True => AnyValue::Bool(false),
KeyPart::False => AnyValue::Bool(true),
KeyPart::False => AnyValue::Bool(false),
KeyPart::True => AnyValue::Bool(true),
KeyPart::Float(n) => AnyValue::Number(n),
KeyPart::Int(n) => AnyValue::BigInt(n),
KeyPart::String(s) => AnyValue::String(s),
@ -499,6 +499,16 @@ where
resource.db.clone()
};
for key in checks
.iter()
.map(|c| &c.0)
.chain(mutations.iter().map(|m| &m.0))
{
if key.is_empty() {
return Err(type_error("key cannot be empty"));
}
}
let checks = checks
.into_iter()
.map(TryInto::try_into)