1use std::{borrow::Cow, collections::Bound};
5
6use reifydb_codec::key::{
7 ByteSink, decode_u64_from,
8 deserializer::KeyDeserializer,
9 encode_u64,
10 encoded::{EncodedKey, EncodedKeyBuilder, EncodedKeyRange},
11 serializer::KeySerializer,
12};
13use reifydb_macro::KeyCodec;
14use reifydb_value::{
15 Result,
16 value::{dictionary::DictionaryId, sumtype::SumTypeId},
17};
18
19use super::{KeyRangeCodec, KeyTag};
20use crate::{
21 interface::catalog::{
22 id::{
23 BindingId, ColumnId, ColumnPropertyId, HandlerId, IndexId, NamespaceId, PrimaryKeyId,
24 RelationshipId, SinkId, SourceId, TableId, ViewId,
25 },
26 object::ObjectId,
27 },
28 key::{
29 any::{Field, KeyFields, RawEncoding, Width, index_tag},
30 bound::{TaggedKeyBound, TaggedKeyBoundRange, object_fields},
31 },
32 return_internal_error,
33 value::index::{encoded::EncodedIndexKey, range::EncodedIndexKeyRange},
34};
35
36pub fn serialize_object_id<B: ByteSink>(object: &ObjectId, out: &mut B) {
37 out.push(object.type_tag());
38 out.extend_from_slice(&encode_u64(object.as_u64()));
39}
40
41pub fn deserialize_object_id(input: &mut &[u8]) -> Result<ObjectId> {
42 if input.is_empty() {
43 return_internal_error!("Invalid ObjectId encoding: empty input");
44 }
45
46 let type_byte = input[0];
47 *input = &input[1..];
48 let id = decode_u64_from(input)?;
49
50 match ObjectId::from_type_tag(type_byte, id) {
51 Some(object) => Ok(object),
52 None => return_internal_error!("Invalid ObjectId type byte: 0x{:02x}.", type_byte),
53 }
54}
55
56pub fn serialize_index_id<B: ByteSink>(index: &IndexId, out: &mut B) {
57 match index {
58 IndexId::Primary(PrimaryKeyId(id)) => {
59 out.push(0x01);
60 out.extend_from_slice(&encode_u64(*id));
61 }
62 }
63}
64
65pub fn deserialize_index_id(input: &mut &[u8]) -> Result<IndexId> {
66 if input.is_empty() {
67 return_internal_error!("Invalid IndexId encoding: empty input");
68 }
69
70 let type_byte = input[0];
71 *input = &input[1..];
72 let id = decode_u64_from(input)?;
73
74 match type_byte {
75 0x01 => Ok(IndexId::Primary(PrimaryKeyId(id))),
76
77 _ => return_internal_error!("Invalid IndexId type byte: 0x{:02x}.", type_byte),
78 }
79}
80
81pub trait KeySerializerCatalogExt {
82 fn extend_object_id(&mut self, object: impl Into<ObjectId>) -> &mut Self;
83 fn extend_index_id(&mut self, index: impl Into<IndexId>) -> &mut Self;
84}
85
86impl KeySerializerCatalogExt for KeySerializer {
87 fn extend_object_id(&mut self, object: impl Into<ObjectId>) -> &mut Self {
88 let mut buf = Vec::new();
89 serialize_object_id(&object.into(), &mut buf);
90 self.extend_raw(&buf);
91 self
92 }
93
94 fn extend_index_id(&mut self, index: impl Into<IndexId>) -> &mut Self {
95 let mut buf = Vec::new();
96 serialize_index_id(&index.into(), &mut buf);
97 self.extend_raw(&buf);
98 self
99 }
100}
101
102pub trait KeyDeserializerCatalogExt {
103 fn read_object_id(&mut self) -> Result<ObjectId>;
104 fn read_index_id(&mut self) -> Result<IndexId>;
105}
106
107impl KeyDeserializerCatalogExt for KeyDeserializer<'_> {
108 fn read_object_id(&mut self) -> Result<ObjectId> {
109 let mut slice = self.remaining_bytes();
110 let before = slice.len();
111 let object_id = deserialize_object_id(&mut slice)?;
112 self.read_raw(before - slice.len())?;
113 Ok(object_id)
114 }
115
116 fn read_index_id(&mut self) -> Result<IndexId> {
117 let mut slice = self.remaining_bytes();
118 let before = slice.len();
119 let index_id = deserialize_index_id(&mut slice)?;
120 self.read_raw(before - slice.len())?;
121 Ok(index_id)
122 }
123}
124
125pub trait EncodedKeyBuilderCatalogExt {
126 fn object_id(self, object: impl Into<ObjectId>) -> Self;
127 fn index_id(self, index: impl Into<IndexId>) -> Self;
128}
129
130impl EncodedKeyBuilderCatalogExt for EncodedKeyBuilder {
131 fn object_id(self, object: impl Into<ObjectId>) -> Self {
132 let mut buf = Vec::new();
133 serialize_object_id(&object.into(), &mut buf);
134 self.raw(&buf)
135 }
136
137 fn index_id(self, index: impl Into<IndexId>) -> Self {
138 let mut buf = Vec::new();
139 serialize_index_id(&index.into(), &mut buf);
140 self.raw(&buf)
141 }
142}
143
144#[cfg(test)]
145pub mod index_entry_key_tests {
146 use reifydb_codec::key::encode_u64;
147
148 use super::{
149 serialize_index_id as serialize_index_id_inner, serialize_object_id as serialize_object_id_inner, *,
150 };
151 use crate::interface::catalog::vtable::VTableId;
152
153 fn serialize_object_id(object: &ObjectId) -> Vec<u8> {
154 let mut out = Vec::new();
155 serialize_object_id_inner(object, &mut out);
156 out
157 }
158
159 fn serialize_index_id(index: &IndexId) -> Vec<u8> {
160 let mut out = Vec::new();
161 serialize_index_id_inner(index, &mut out);
162 out
163 }
164
165 #[test]
166 fn test_object_id_ordering() {
167 let object1 = ObjectId::table(1);
168 let object2 = ObjectId::table(2);
169 let object100 = ObjectId::table(100);
170 let object200 = ObjectId::table(200);
171
172 let bytes1 = serialize_object_id(&object1);
173 let bytes2 = serialize_object_id(&object2);
174 let bytes100 = serialize_object_id(&object100);
175 let bytes200 = serialize_object_id(&object200);
176
177 assert!(bytes2 < bytes1, "object(2) should be < object(1) in bytes");
178 assert!(bytes200 < bytes100, "object(200) should be < object(100) in bytes");
179 assert!(bytes100 < bytes2, "object(100) should be < object(2) in bytes");
180 }
181
182 #[test]
183 fn test_range_boundaries() {
184 let object10 = ObjectId::table(10);
185 let object9 = object10.prev();
186
187 let bytes10 = serialize_object_id(&object10);
188 let bytes9 = serialize_object_id(&object9);
189
190 assert!(bytes9 > bytes10, "object(9) should be > object(10) in bytes");
191
192 let view10 = ObjectId::view(10);
193 let view9 = view10.prev();
194
195 let vbytes10 = serialize_object_id(&view10);
196 let vbytes9 = serialize_object_id(&view9);
197
198 assert!(vbytes9 > vbytes10, "view(9) should be > view(10) in bytes");
199
200 let virtual10 = ObjectId::vtable(10);
201 let virtual9 = virtual10.prev();
202
203 let tvbytes10 = serialize_object_id(&virtual10);
204 let tvbytes9 = serialize_object_id(&virtual9);
205
206 assert!(tvbytes9 > tvbytes10, "vtable(9) should be > vtable(10) in bytes");
207
208 assert_ne!(bytes10, vbytes10, "table(10) should != view(10)");
209 assert_ne!(bytes10, tvbytes10, "table(10) should != vtable(10)");
210 assert_ne!(vbytes10, tvbytes10, "view(10) should != vtable(10)");
211 assert_eq!(bytes10[0], 0x01, "table type byte should be 0x01");
212 assert_eq!(vbytes10[0], 0x02, "view type byte should be 0x02");
213 assert_eq!(tvbytes10[0], 0x03, "vtable type byte should be 0x03");
214
215 let row_key_10_100 = vec![0xFC];
216 let mut key1 = row_key_10_100.clone();
217 key1.extend(&bytes10);
218 key1.extend(&encode_u64(100u64));
219
220 let mut key2 = row_key_10_100.clone();
221 key2.extend(&bytes10);
222 key2.extend(&encode_u64(200u64));
223
224 let mut end_key = vec![0xFC];
225 end_key.extend(&bytes9);
226
227 assert!(key1 >= bytes10, "key1 should be >= start(object10)");
228 assert!(key1 < end_key, "key1 should be < end(object9)");
229 assert!(key2 >= bytes10, "key2 should be >= start(object10)");
230 assert!(key2 < end_key, "key2 should be < end(object9)");
231 }
232
233 #[test]
234 fn test_vtable_serialization() {
235 let virtual_object = ObjectId::vtable(42);
236 let bytes = serialize_object_id(&virtual_object);
237 let mut slice = &bytes[..];
238 let deserialized = deserialize_object_id(&mut slice).unwrap();
239 assert_eq!(virtual_object, deserialized);
240 assert!(slice.is_empty());
241
242 assert_eq!(bytes[0], 0x03);
243
244 let virtual_id = VTableId(123);
245 let object_from_id = ObjectId::from(virtual_id);
246 let bytes_from_id = serialize_object_id(&object_from_id);
247 let mut slice = &bytes_from_id[..];
248 let deserialized_id = deserialize_object_id(&mut slice).unwrap();
249 assert_eq!(object_from_id, deserialized_id);
250 assert!(slice.is_empty());
251
252 let virtual1 = ObjectId::vtable(1);
253 let virtual2 = ObjectId::vtable(2);
254 let bytes1 = serialize_object_id(&virtual1);
255 let bytes2 = serialize_object_id(&virtual2);
256
257 assert!(bytes2 < bytes1, "vtable(2) should be < vtable(1) in bytes");
258 }
259
260 #[test]
261 fn test_index_id_serialization() {
262 let index = IndexId::primary(42);
263 let bytes = serialize_index_id(&index);
264 let mut slice = &bytes[..];
265 let deserialized = deserialize_index_id(&mut slice).unwrap();
266 assert_eq!(index.as_u64(), deserialized.as_u64());
267 assert!(slice.is_empty());
268
269 assert_eq!(bytes[0], 0x01);
270
271 let primary_id = PrimaryKeyId(123);
272 let index_from_id = IndexId::Primary(primary_id);
273 let bytes_from_id = serialize_index_id(&index_from_id);
274 let mut slice = &bytes_from_id[..];
275 let deserialized_id = deserialize_index_id(&mut slice).unwrap();
276 assert_eq!(index_from_id.as_u64(), deserialized_id.as_u64());
277 assert!(slice.is_empty());
278 }
279
280 #[test]
281 fn test_index_id_ordering() {
282 let index1 = IndexId::primary(1);
283 let index2 = IndexId::primary(2);
284 let index100 = IndexId::primary(100);
285 let index200 = IndexId::primary(200);
286
287 let bytes1 = serialize_index_id(&index1);
288 let bytes2 = serialize_index_id(&index2);
289 let bytes100 = serialize_index_id(&index100);
290 let bytes200 = serialize_index_id(&index200);
291
292 assert!(bytes2 < bytes1, "index(2) should be < index(1) in bytes");
293 assert!(bytes200 < bytes100, "index(200) should be < index(100) in bytes");
294 assert!(bytes100 < bytes2, "index(100) should be < index(2) in bytes");
295 }
296
297 #[test]
298 fn test_index_id_range_boundaries() {
299 let index10 = IndexId::primary(10);
300 let index11 = IndexId::primary(11);
301
302 let bytes10 = serialize_index_id(&index10);
303 let bytes11 = serialize_index_id(&index11);
304
305 assert!(bytes11 < bytes10, "index(11) should be < index(10) in bytes");
306
307 assert_eq!(bytes10.len(), 9, "IndexId(10) should be 9 bytes");
308 assert_eq!(bytes10[0], 0x01, "Primary variant should have type byte 0x01");
309
310 let next_index = IndexId::primary(11);
311 let next_bytes = serialize_index_id(&next_index);
312
313 assert!(next_bytes < bytes10, "index(11) should be < index(10) for proper range boundaries");
314 }
315
316 #[test]
317 fn test_index_entry_key_encoding_with_discriminator() {
318 let object = ObjectId::table(42);
319 let index = IndexId::primary(7);
320
321 let object_bytes = serialize_object_id(&object);
322 let index_bytes = serialize_index_id(&index);
323
324 assert_eq!(object_bytes.len(), 9, "ObjectId(42) should be 9 bytes");
325 assert_eq!(index_bytes.len(), 9, "IndexId(7) should be 9 bytes");
326
327 assert_eq!(object_bytes[0], 0x01, "Table object should have type byte 0x01");
328 assert_eq!(index_bytes[0], 0x01, "Primary index should have type byte 0x01");
329
330 let total_prefix_size = 1 + 1 + object_bytes.len() + index_bytes.len();
331 assert_eq!(total_prefix_size, 20, "Total IndexEntryKey prefix should be 20 bytes");
332 }
333}
334
335#[cfg(test)]
336mod moved_catalog_key_tests {
337 use reifydb_codec::key::{deserializer::KeyDeserializer, serializer::KeySerializer};
338
339 use super::{KeyDeserializerCatalogExt, KeySerializerCatalogExt};
340 use crate::interface::catalog::{
341 id::{IndexId, PrimaryKeyId, TableId},
342 object::ObjectId,
343 };
344
345 #[test]
346 fn test_index_id() {
347 let mut serializer = KeySerializer::new();
348 serializer.extend_index_id(IndexId::Primary(PrimaryKeyId(123456789)));
349 let result = serializer.finish();
350
351 assert_eq!(result.len(), 9);
353 assert_eq!(result[0], 0x01); let mut serializer2 = KeySerializer::new();
358 serializer2.extend_index_id(IndexId::Primary(PrimaryKeyId(1)));
359 let result2 = serializer2.finish();
360
361 assert!(result2[1..] > result[1..]);
362 }
363
364 #[test]
365 fn test_object_id() {
366 let mut serializer = KeySerializer::new();
367 serializer.extend_object_id(ObjectId::Table(TableId(987654321)));
368 let result = serializer.finish();
369
370 assert_eq!(result.len(), 9);
372 assert_eq!(result[0], 0x01); let mut serializer2 = KeySerializer::new();
376 serializer2.extend_object_id(ObjectId::Table(TableId(987654322)));
377 let result2 = serializer2.finish();
378
379 assert!(result2[1..] < result[1..]);
380 }
381
382 #[test]
383 fn test_read_object_id() {
384 let mut ser = KeySerializer::new();
385 let object = ObjectId::table(42);
386 ser.extend_object_id(object);
387 let bytes = ser.finish();
388
389 let mut de = KeyDeserializer::from_bytes(&bytes);
390 assert_eq!(de.read_object_id().unwrap(), object);
391 assert!(de.is_empty());
392 }
393
394 #[test]
395 fn test_read_index_id() {
396 let mut ser = KeySerializer::new();
397 let index = IndexId::primary(999);
398 ser.extend_index_id(index);
399 let bytes = ser.finish();
400
401 let mut de = KeyDeserializer::from_bytes(&bytes);
402 assert_eq!(de.read_index_id().unwrap(), index);
403 assert!(de.is_empty());
404 }
405}
406
407#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
408#[key(tag = Dictionary)]
409pub struct DictionaryKey {
410 pub dictionary: DictionaryId,
411}
412
413impl DictionaryKey {
414 pub fn new(dictionary: DictionaryId) -> Self {
415 Self {
416 dictionary,
417 }
418 }
419
420 pub fn encoded(dictionary: impl Into<DictionaryId>) -> EncodedKey {
421 Self::new(dictionary.into()).encode()
422 }
423
424 pub fn full_scan() -> TaggedKeyBoundRange {
425 TaggedKeyBoundRange::kind(Self::TAG)
426 }
427}
428
429#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
430#[key(tag = DictionaryEntry)]
431pub struct DictionaryEntryKey {
432 pub dictionary: DictionaryId,
433 pub hash: [u8; 16],
434}
435
436impl DictionaryEntryKey {
437 pub fn new(dictionary: DictionaryId, hash: [u8; 16]) -> Self {
438 Self {
439 dictionary,
440 hash,
441 }
442 }
443
444 pub fn encoded(dictionary: impl Into<DictionaryId>, hash: [u8; 16]) -> EncodedKey {
445 Self::new(dictionary.into(), hash).encode()
446 }
447
448 pub fn full_scan(dictionary: DictionaryId) -> TaggedKeyBoundRange {
449 TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, dictionary.0 as u128)])
450 }
451}
452
453#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
454#[key(tag = DictionaryEntryIndex)]
455pub struct DictionaryEntryIndexKey {
456 pub dictionary: DictionaryId,
457 #[key(varint)]
458 pub id: u128,
459}
460
461impl DictionaryEntryIndexKey {
462 pub fn new(dictionary: DictionaryId, id: u128) -> Self {
463 Self {
464 dictionary,
465 id,
466 }
467 }
468
469 pub fn encoded(dictionary: impl Into<DictionaryId>, id: u128) -> EncodedKey {
470 Self::new(dictionary.into(), id).encode()
471 }
472
473 pub fn full_scan(dictionary: DictionaryId) -> TaggedKeyBoundRange {
474 TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, dictionary.0 as u128)])
475 }
476}
477
478#[derive(Debug, Clone, PartialEq)]
479pub struct DictionaryEntryIndexKeyRange {
480 pub dictionary: DictionaryId,
481 pub start_id: Option<u128>,
482 pub end_id: Option<u128>,
483}
484
485impl DictionaryEntryIndexKeyRange {
486 pub fn new(dictionary: DictionaryId, start_id: Option<u128>, end_id: Option<u128>) -> Self {
487 Self {
488 dictionary,
489 start_id,
490 end_id,
491 }
492 }
493
494 pub fn full(dictionary: DictionaryId) -> Self {
495 Self {
496 dictionary,
497 start_id: None,
498 end_id: None,
499 }
500 }
501}
502
503impl KeyRangeCodec for DictionaryEntryIndexKeyRange {
504 const TAG: KeyTag = KeyTag::DictionaryEntryIndex;
505
506 fn start(&self) -> Option<EncodedKey> {
507 let mut serializer = KeySerializer::with_capacity(25);
508 serializer.extend_u8(Self::TAG as u8).extend_u64(self.dictionary);
509 if let Some(id) = self.start_id {
510 serializer.extend_u128_varint(id);
511 }
512 Some(serializer.to_encoded_key())
513 }
514
515 fn end(&self) -> Option<EncodedKey> {
516 if let Some(id) = self.end_id {
517 let mut serializer = KeySerializer::with_capacity(25);
518 serializer.extend_u8(Self::TAG as u8).extend_u64(self.dictionary).extend_u128_varint(id - 1);
519 Some(serializer.to_encoded_key())
520 } else {
521 let mut serializer = KeySerializer::with_capacity(9);
522 serializer.extend_u8(Self::TAG as u8).extend_u64(*self.dictionary - 1);
523 Some(serializer.to_encoded_key())
524 }
525 }
526
527 fn decode(_range: &EncodedKeyRange) -> (Option<Self>, Option<Self>) {
528 (None, None)
529 }
530}
531
532#[cfg(test)]
533pub mod dictionary_key_tests {
534 use std::ops::Bound;
535
536 use super::*;
537
538 #[test]
539 fn test_dictionary_key_encode_decode() {
540 let key = DictionaryKey {
541 dictionary: DictionaryId(0x1234),
542 };
543 let encoded = key.encode();
544 let decoded = DictionaryKey::decode(&encoded).unwrap();
545 assert_eq!(decoded.dictionary, key.dictionary);
546 }
547
548 #[test]
549 fn test_dictionary_entry_key_encode_decode() {
550 let key = DictionaryEntryKey {
551 dictionary: DictionaryId(42),
552 hash: [
553 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
554 0x0f, 0x10,
555 ],
556 };
557 let encoded = key.encode();
558 let decoded = DictionaryEntryKey::decode(&encoded).unwrap();
559 assert_eq!(decoded.dictionary, key.dictionary);
560 assert_eq!(decoded.hash, key.hash);
561 }
562
563 #[test]
564 fn a_dictionary_entry_hash_made_of_0xff_bytes_still_round_trips() {
565 let key = DictionaryEntryKey {
568 dictionary: DictionaryId(42),
569 hash: [0xff; 16],
570 };
571 let encoded = key.encode();
572 assert_eq!(encoded.len(), 1 + 8 + 16);
573 assert_eq!(DictionaryEntryKey::decode(&encoded).unwrap(), key);
574 }
575
576 #[test]
577 fn test_dictionary_entry_index_key_encode_decode() {
578 let key = DictionaryEntryIndexKey {
579 dictionary: DictionaryId(99),
580 id: 12345,
581 };
582 let encoded = key.encode();
583 let decoded = DictionaryEntryIndexKey::decode(&encoded).unwrap();
584 assert_eq!(decoded.dictionary, key.dictionary);
585 assert_eq!(decoded.id, key.id);
586 }
587
588 #[test]
589 fn test_dictionary_key_full_scan() {
590 let range = DictionaryKey::full_scan();
591 assert!(matches!(range.start, Bound::Included(_) | Bound::Excluded(_)));
592 assert!(matches!(range.end, Bound::Included(_) | Bound::Excluded(_)));
593 }
594
595 #[test]
596 fn test_dictionary_entry_key_full_scan() {
597 let range = DictionaryEntryKey::full_scan(DictionaryId(42)).encode();
598 assert!(matches!(range.start, Bound::Included(_) | Bound::Excluded(_)));
599 assert!(matches!(range.end, Bound::Included(_) | Bound::Excluded(_)));
600 }
601
602 #[test]
603 fn test_dictionary_entry_index_key_full_scan() {
604 let range = DictionaryEntryIndexKey::full_scan(DictionaryId(42)).encode();
605 assert!(matches!(range.start, Bound::Included(_) | Bound::Excluded(_)));
606 assert!(matches!(range.end, Bound::Included(_) | Bound::Excluded(_)));
607 }
608
609 #[test]
610 fn test_dictionary_entry_index_key_range() {
611 let range = DictionaryEntryIndexKeyRange::full(DictionaryId(42));
612 let start = range.start();
613 let end = range.end();
614 assert!(start.is_some());
615 assert!(end.is_some());
616 }
617}
618
619#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
620#[key(tag = Index)]
621pub struct IndexKey {
622 pub object: ObjectId,
623 pub index: IndexId,
624}
625
626#[derive(Debug, Clone, PartialEq)]
627pub struct ObjectIndexKeyRange {
628 pub object: ObjectId,
629}
630
631impl ObjectIndexKeyRange {
632 fn decode_key(key: &EncodedKey) -> Option<Self> {
633 let mut de = KeyDeserializer::from_bytes(key.as_slice());
634
635 let kind: KeyTag = de.read_u8().ok()?.try_into().ok()?;
636 if kind != Self::TAG {
637 return None;
638 }
639
640 let object = de.read_object_id().ok()?;
641
642 Some(ObjectIndexKeyRange {
643 object,
644 })
645 }
646}
647
648impl KeyRangeCodec for ObjectIndexKeyRange {
649 const TAG: KeyTag = KeyTag::Index;
650
651 fn start(&self) -> Option<EncodedKey> {
652 let mut serializer = KeySerializer::with_capacity(10);
653 serializer.extend_u8(Self::TAG as u8).extend_object_id(self.object);
654 Some(serializer.to_encoded_key())
655 }
656
657 fn end(&self) -> Option<EncodedKey> {
658 let mut serializer = KeySerializer::with_capacity(10);
659 serializer.extend_u8(Self::TAG as u8).extend_object_id(self.object.prev());
660 Some(serializer.to_encoded_key())
661 }
662
663 fn decode(range: &EncodedKeyRange) -> (Option<Self>, Option<Self>)
664 where
665 Self: Sized,
666 {
667 let start_key = match &range.start {
668 Bound::Included(key) | Bound::Excluded(key) => Self::decode_key(key),
669 Bound::Unbounded => None,
670 };
671
672 let end_key = match &range.end {
673 Bound::Included(key) | Bound::Excluded(key) => Self::decode_key(key),
674 Bound::Unbounded => None,
675 };
676
677 (start_key, end_key)
678 }
679}
680
681impl IndexKey {
682 pub fn new(object: impl Into<ObjectId>, index: impl Into<IndexId>) -> Self {
683 Self {
684 object: object.into(),
685 index: index.into(),
686 }
687 }
688
689 pub fn encoded(object: impl Into<ObjectId>, index: impl Into<IndexId>) -> EncodedKey {
690 Self {
691 object: object.into(),
692 index: index.into(),
693 }
694 .encode()
695 }
696
697 pub fn full_scan(object: impl Into<ObjectId>) -> TaggedKeyBoundRange {
698 TaggedKeyBoundRange::prefix(Self::TAG, object_fields(object.into()))
699 }
700}
701
702#[cfg(test)]
703pub mod index_key_tests {
704 use super::IndexKey;
705 use crate::interface::catalog::{id::IndexId, object::ObjectId};
706
707 #[test]
708 fn test_encode_decode() {
709 let key = IndexKey {
710 object: ObjectId::table(0xABCD),
711 index: IndexId::primary(0x123456789ABCDEF0u64),
712 };
713 let encoded = key.encode();
714
715 let expected: Vec<u8> = vec![
716 0xF3, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32, 0xED, 0xCB, 0xA9, 0x87, 0x65, 0x43,
717 0x21, 0x0F,
718 ];
719
720 assert_eq!(encoded.as_slice(), expected);
721
722 let key = IndexKey::decode(&encoded).unwrap();
723 assert_eq!(key.object, 0xABCD);
724 assert_eq!(key.index, 0x123456789ABCDEF0);
725 }
726
727 #[test]
728 fn test_order_preserving() {
729 let key1 = IndexKey {
730 object: ObjectId::table(1),
731 index: IndexId::primary(100),
732 };
733 let key2 = IndexKey {
734 object: ObjectId::table(1),
735 index: IndexId::primary(200),
736 };
737 let key3 = IndexKey {
738 object: ObjectId::table(2),
739 index: IndexId::primary(50),
740 };
741
742 let encoded1 = key1.encode();
743 let encoded2 = key2.encode();
744 let encoded3 = key3.encode();
745
746 assert!(encoded3 < encoded2, "ordering not preserved");
747 assert!(encoded2 < encoded1, "ordering not preserved");
748 }
749}
750
751#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
752#[key(tag = IndexEntry)]
753pub struct IndexEntryKey {
754 pub object: ObjectId,
755 #[key(tagged)]
756 pub index: IndexId,
757 pub key: EncodedIndexKey,
758}
759
760impl IndexEntryKey {
761 pub fn new(object: impl Into<ObjectId>, index: IndexId, key: EncodedIndexKey) -> Self {
762 Self {
763 object: object.into(),
764 index,
765 key,
766 }
767 }
768}
769
770#[derive(Debug, Clone, PartialEq)]
771pub struct IndexEntryKeyRange {
772 pub object: ObjectId,
773 pub index: IndexId,
774}
775
776impl IndexEntryKeyRange {
777 fn decode_key(key: &EncodedKey) -> Option<Self> {
778 let mut de = KeyDeserializer::from_bytes(key.as_slice());
779
780 let kind: KeyTag = de.read_u8().ok()?.try_into().ok()?;
781 if kind != Self::TAG {
782 return None;
783 }
784
785 let object = de.read_object_id().ok()?;
786 let index = de.read_index_id().ok()?;
787
788 Some(IndexEntryKeyRange {
789 object,
790 index,
791 })
792 }
793}
794
795impl KeyRangeCodec for IndexEntryKeyRange {
796 const TAG: KeyTag = KeyTag::IndexEntry;
797
798 fn start(&self) -> Option<EncodedKey> {
799 let mut serializer = KeySerializer::with_capacity(19);
800 serializer.extend_u8(Self::TAG as u8).extend_object_id(self.object).extend_index_id(self.index);
801 Some(serializer.to_encoded_key())
802 }
803
804 fn end(&self) -> Option<EncodedKey> {
805 let mut serializer = KeySerializer::with_capacity(19);
806 serializer.extend_u8(Self::TAG as u8).extend_object_id(self.object).extend_index_id(self.index.prev());
807 Some(serializer.to_encoded_key())
808 }
809
810 fn decode(range: &EncodedKeyRange) -> (Option<Self>, Option<Self>)
811 where
812 Self: Sized,
813 {
814 let start_key = match &range.start {
815 Bound::Included(key) | Bound::Excluded(key) => Self::decode_key(key),
816 Bound::Unbounded => None,
817 };
818
819 let end_key = match &range.end {
820 Bound::Included(key) | Bound::Excluded(key) => Self::decode_key(key),
821 Bound::Unbounded => None,
822 };
823
824 (start_key, end_key)
825 }
826}
827
828impl IndexEntryKey {
829 pub fn index_range(object: impl Into<ObjectId>, index: IndexId) -> TaggedKeyBoundRange {
830 let object = object.into();
831 TaggedKeyBoundRange::prefix(
832 <IndexEntryKeyRange as KeyRangeCodec>::TAG,
833 object_fields(object)
834 .into_iter()
835 .chain([Field::UAsc(Width::U8, 1), Field::UDesc(Width::U64, index.as_u64() as u128)]),
836 )
837 }
838
839 pub fn key_prefix_range(object: impl Into<ObjectId>, index: IndexId, key_prefix: &[u8]) -> TaggedKeyBoundRange {
840 let object = object.into();
841 TaggedKeyBoundRange::prefix(
842 KeyTag::IndexEntry,
843 object_fields(object).into_iter().chain([
844 Field::UAsc(Width::U8, 1),
845 Field::UDesc(Width::U64, index.as_u64() as u128),
846 Field::RawAsc(RawEncoding::Verbatim, Cow::Owned(key_prefix.to_vec())),
847 ]),
848 )
849 }
850
851 pub fn key_range(
852 object: impl Into<ObjectId>,
853 index: IndexId,
854 index_range: EncodedIndexKeyRange,
855 ) -> TaggedKeyBoundRange {
856 let object = object.into();
857 let head = || {
858 object_fields(object)
859 .into_iter()
860 .chain([Field::UAsc(Width::U8, 1), Field::UDesc(Width::U64, index.as_u64() as u128)])
861 };
862 let at = |key: &EncodedIndexKey| {
863 TaggedKeyBound::prefix(
864 KeyTag::IndexEntry,
865 head().chain([Field::RawAsc(
866 RawEncoding::Verbatim,
867 Cow::Owned(key.as_slice().to_vec()),
868 )]),
869 )
870 };
871
872 let start = match &index_range.start {
873 Bound::Included(key) => Bound::Included(at(key)),
874 Bound::Excluded(key) => Bound::Excluded(at(key)),
875 Bound::Unbounded => Bound::Included(TaggedKeyBound::prefix(KeyTag::IndexEntry, head())),
876 };
877
878 let end = match &index_range.end {
879 Bound::Included(key) => Bound::Included(at(key)),
880 Bound::Excluded(key) => Bound::Excluded(at(key)),
881 Bound::Unbounded => Bound::Excluded(TaggedKeyBound::prefix_end(KeyTag::IndexEntry, head())),
882 };
883
884 TaggedKeyBoundRange {
885 start,
886 end,
887 }
888 }
889}
890
891#[cfg(test)]
892pub mod index_entry_key_tests_2 {
893 use reifydb_value::value::value_type::ValueType;
894
895 use super::*;
896 use crate::{sort::SortDirection, value::index::shape::IndexShape};
897
898 #[test]
899 fn test_encode_decode() {
900 let layout = IndexShape::new(
901 &[ValueType::Uint8, ValueType::Uint8],
902 &[SortDirection::Asc, SortDirection::Asc],
903 )
904 .unwrap();
905
906 let mut index_key = layout.allocate_key();
907 layout.set_u64(&mut index_key, 0, 100u64);
908 layout.set_row_number(&mut index_key, 1, 1u64);
909
910 let entry = IndexEntryKey {
911 object: ObjectId::table(42),
912 index: IndexId::primary(7),
913 key: index_key.clone(),
914 };
915
916 let encoded = entry.encode();
917 let decoded = IndexEntryKey::decode(&encoded).unwrap();
918
919 assert_eq!(decoded.object, ObjectId::table(42));
920 assert_eq!(decoded.index, IndexId::primary(7));
921 assert_eq!(decoded.key.as_slice(), index_key.as_slice());
922 }
923
924 #[test]
925 fn test_ordering() {
926 let layout = IndexShape::new(&[ValueType::Uint8], &[SortDirection::Asc]).unwrap();
927
928 let mut key1 = layout.allocate_key();
929 layout.set_u64(&mut key1, 0, 100u64);
930
931 let mut key2 = layout.allocate_key();
932 layout.set_u64(&mut key2, 0, 200u64);
933
934 let entry1 = IndexEntryKey {
935 object: ObjectId::table(1),
936 index: IndexId::primary(1),
937 key: key1,
938 };
939
940 let entry2 = IndexEntryKey {
941 object: ObjectId::table(1),
942 index: IndexId::primary(1),
943 key: key2,
944 };
945
946 let encoded1 = entry1.encode();
947 let encoded2 = entry2.encode();
948
949 assert!(encoded1.as_slice() < encoded2.as_slice());
950 }
951
952 #[test]
953 fn test_index_range() {
954 let range = IndexEntryKey::index_range(ObjectId::table(10), IndexId::primary(5)).encode();
955
956 let layout = IndexShape::new(&[ValueType::Uint8], &[SortDirection::Asc]).unwrap();
957
958 let mut key = layout.allocate_key();
959 layout.set_u64(&mut key, 0, 50u64);
960
961 let entry = IndexEntryKey {
962 object: ObjectId::table(10),
963 index: IndexId::primary(5),
964 key,
965 };
966
967 let encoded = entry.encode();
968
969 if let (Bound::Included(start), Bound::Excluded(end)) = (&range.start, &range.end) {
970 assert!(encoded.as_slice() >= start.as_slice());
971 assert!(encoded.as_slice() < end.as_slice());
972 } else {
973 panic!("Expected Included/Excluded bounds");
974 }
975
976 let entry2 = IndexEntryKey {
977 object: ObjectId::table(10),
978 index: IndexId::primary(6),
979 key: layout.allocate_key(),
980 };
981
982 let encoded2 = entry2.encode();
983
984 if let (Bound::Included(start), Bound::Excluded(end)) = (&range.start, &range.end) {
985 assert!(encoded2.as_slice() < start.as_slice() || encoded2.as_slice() >= end.as_slice());
986 }
987 }
988
989 #[test]
990 fn test_key_prefix_range() {
991 let layout = IndexShape::new(
992 &[ValueType::Uint8, ValueType::Uint8],
993 &[SortDirection::Asc, SortDirection::Asc],
994 )
995 .unwrap();
996
997 let mut key = layout.allocate_key();
998 layout.set_u64(&mut key, 0, 100u64);
999 layout.set_row_number(&mut key, 1, 0u64);
1000
1001 let prefix = &key.as_slice()[..layout.fields[1].offset];
1002 let range = IndexEntryKey::key_prefix_range(ObjectId::table(1), IndexId::primary(1), prefix).encode();
1003
1004 layout.set_row_number(&mut key, 1, 999u64);
1005 let entry = IndexEntryKey {
1006 object: ObjectId::table(1),
1007 index: IndexId::primary(1),
1008 key: key.clone(),
1009 };
1010
1011 let encoded = entry.encode();
1012
1013 if let (Bound::Included(start), Bound::Excluded(end)) = (&range.start, &range.end) {
1014 assert!(encoded.as_slice() >= start.as_slice());
1015 assert!(encoded.as_slice() < end.as_slice());
1016 }
1017
1018 let mut key2 = layout.allocate_key();
1019 layout.set_u64(&mut key2, 0, 200u64);
1020 layout.set_row_number(&mut key2, 1, 1u64);
1021
1022 let entry2 = IndexEntryKey {
1023 object: ObjectId::table(1),
1024 index: IndexId::primary(1),
1025 key: key2,
1026 };
1027
1028 let encoded2 = entry2.encode();
1029
1030 if let Bound::Excluded(end) = &range.end {
1031 assert!(encoded2.as_slice() >= end.as_slice());
1032 }
1033 }
1034}
1035
1036#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
1037#[key(tag = SumType)]
1038pub struct SumTypeKey {
1039 pub sumtype: SumTypeId,
1040}
1041
1042impl SumTypeKey {
1043 pub fn new(sumtype: SumTypeId) -> Self {
1044 Self {
1045 sumtype,
1046 }
1047 }
1048
1049 pub fn full_scan() -> TaggedKeyBoundRange {
1050 TaggedKeyBoundRange::kind(Self::TAG)
1051 }
1052}
1053
1054#[cfg(test)]
1055mod sum_type_key_tests {
1056 use reifydb_value::value::sumtype::SumTypeId;
1057
1058 use super::SumTypeKey;
1059
1060 #[test]
1061 fn test_encode_decode() {
1062 let key = SumTypeKey {
1063 sumtype: SumTypeId(0xABCD),
1064 };
1065 let encoded = key.encode();
1066 let decoded = SumTypeKey::decode(&encoded).unwrap();
1067 assert_eq!(decoded.sumtype, SumTypeId(0xABCD));
1068 }
1069}
1070
1071#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
1072#[key(tag = View)]
1073pub struct ViewKey {
1074 pub view: ViewId,
1075}
1076
1077impl ViewKey {
1078 pub fn new(view: impl Into<ViewId>) -> Self {
1079 Self {
1080 view: view.into(),
1081 }
1082 }
1083
1084 pub fn full_scan() -> TaggedKeyBoundRange {
1085 TaggedKeyBoundRange::kind(Self::TAG)
1086 }
1087}
1088
1089#[cfg(test)]
1090pub mod view_key_tests {
1091 use super::ViewKey;
1092 use crate::interface::catalog::id::ViewId;
1093
1094 #[test]
1095 fn test_encode_decode() {
1096 let key = ViewKey {
1097 view: ViewId(0xABCD),
1098 };
1099 let encoded = key.encode();
1100 let expected = vec![0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32];
1101 assert_eq!(encoded.as_slice(), expected);
1102
1103 let key = ViewKey::decode(&encoded).unwrap();
1104 assert_eq!(key.view, 0xABCD);
1105 }
1106}
1107
1108#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
1109#[key(tag = Table)]
1110pub struct TableKey {
1111 pub table: TableId,
1112}
1113
1114impl TableKey {
1115 pub fn new(table: impl Into<TableId>) -> Self {
1116 Self {
1117 table: table.into(),
1118 }
1119 }
1120
1121 pub fn encoded(table: impl Into<TableId>) -> EncodedKey {
1122 Self::new(table).encode()
1123 }
1124
1125 pub fn full_scan() -> TaggedKeyBoundRange {
1126 TaggedKeyBoundRange::kind(Self::TAG)
1127 }
1128}
1129
1130#[cfg(test)]
1131pub mod table_key_tests {
1132 use super::TableKey;
1133 use crate::interface::catalog::id::TableId;
1134
1135 #[test]
1136 fn test_encode_decode() {
1137 let key = TableKey {
1138 table: TableId(0xABCD),
1139 };
1140 let encoded = key.encode();
1141 let expected = vec![0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32];
1142 assert_eq!(encoded.as_slice(), expected);
1143
1144 let key = TableKey::decode(&encoded).unwrap();
1145 assert_eq!(key.table, 0xABCD);
1146 }
1147
1148 #[test]
1149 fn test_order_preserving() {
1150 let key1 = TableKey {
1151 table: TableId(1),
1152 };
1153 let key2 = TableKey {
1154 table: TableId(2),
1155 };
1156
1157 let encoded1 = key1.encode();
1158 let encoded2 = key2.encode();
1159
1160 assert!(encoded2 < encoded1, "ordering not preserved");
1161 }
1162}
1163
1164#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
1165#[key(tag = Source)]
1166pub struct SourceKey {
1167 pub source: SourceId,
1168}
1169
1170impl SourceKey {
1171 pub fn new(source: impl Into<SourceId>) -> Self {
1172 Self {
1173 source: source.into(),
1174 }
1175 }
1176
1177 pub fn full_scan() -> TaggedKeyBoundRange {
1178 TaggedKeyBoundRange::kind(Self::TAG)
1179 }
1180}
1181
1182#[cfg(test)]
1183pub mod source_key_tests {
1184 use super::SourceKey;
1185 use crate::interface::catalog::id::SourceId;
1186
1187 #[test]
1188 fn test_encode_decode() {
1189 let key = SourceKey {
1190 source: SourceId(0x1234),
1191 };
1192 let encoded = key.encode();
1193 let decoded = SourceKey::decode(&encoded).unwrap();
1194 assert_eq!(decoded.source, SourceId(0x1234));
1195 assert_eq!(key, decoded);
1196 }
1197}
1198
1199#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
1200#[key(tag = Sink)]
1201pub struct SinkKey {
1202 pub sink: SinkId,
1203}
1204
1205impl SinkKey {
1206 pub fn new(sink: impl Into<SinkId>) -> Self {
1207 Self {
1208 sink: sink.into(),
1209 }
1210 }
1211
1212 pub fn full_scan() -> TaggedKeyBoundRange {
1213 TaggedKeyBoundRange::kind(Self::TAG)
1214 }
1215}
1216
1217#[cfg(test)]
1218pub mod sink_key_tests {
1219 use super::SinkKey;
1220 use crate::interface::catalog::id::SinkId;
1221
1222 #[test]
1223 fn test_encode_decode() {
1224 let key = SinkKey {
1225 sink: SinkId(0x1234),
1226 };
1227 let encoded = key.encode();
1228 let decoded = SinkKey::decode(&encoded).unwrap();
1229 assert_eq!(decoded.sink, SinkId(0x1234));
1230 assert_eq!(key, decoded);
1231 }
1232}
1233
1234#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
1235#[key(tag = Relationship)]
1236pub struct RelationshipKey {
1237 pub relationship: RelationshipId,
1238}
1239
1240impl RelationshipKey {
1241 pub fn new(relationship: impl Into<RelationshipId>) -> Self {
1242 Self {
1243 relationship: relationship.into(),
1244 }
1245 }
1246
1247 pub fn encoded(relationship: impl Into<RelationshipId>) -> EncodedKey {
1248 Self::new(relationship).encode()
1249 }
1250
1251 pub fn full_scan() -> TaggedKeyBoundRange {
1252 TaggedKeyBoundRange::kind(Self::TAG)
1253 }
1254}
1255
1256#[cfg(test)]
1257mod relationship_key_tests {
1258 use super::RelationshipKey;
1259 use crate::interface::catalog::id::RelationshipId;
1260
1261 #[test]
1262 fn test_encode_decode() {
1263 let key = RelationshipKey {
1264 relationship: RelationshipId(0xABCD),
1265 };
1266 let encoded = key.encode();
1267 let decoded = RelationshipKey::decode(&encoded).unwrap();
1268 assert_eq!(decoded.relationship, RelationshipId(0xABCD));
1269 }
1270}
1271
1272#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
1273#[key(tag = ColumnProperty)]
1274pub struct ColumnPropertyKey {
1275 pub column: ColumnId,
1276 pub property: ColumnPropertyId,
1277}
1278
1279impl ColumnPropertyKey {
1280 pub fn new(column: impl Into<ColumnId>, property: impl Into<ColumnPropertyId>) -> Self {
1281 Self {
1282 column: column.into(),
1283 property: property.into(),
1284 }
1285 }
1286
1287 pub fn encoded(column: impl Into<ColumnId>, property: impl Into<ColumnPropertyId>) -> EncodedKey {
1288 Self::new(column, property).encode()
1289 }
1290
1291 pub fn full_scan(column: ColumnId) -> TaggedKeyBoundRange {
1292 TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, column.0 as u128)])
1293 }
1294}
1295
1296#[cfg(test)]
1297pub mod column_property_key_tests {
1298 use super::ColumnPropertyKey;
1299 use crate::interface::catalog::id::{ColumnId, ColumnPropertyId};
1300
1301 #[test]
1302 fn test_encode_decode() {
1303 let key = ColumnPropertyKey {
1304 column: ColumnId(0xABCD),
1305 property: ColumnPropertyId(0x123456789ABCDEF0),
1306 };
1307 let encoded = key.encode();
1308
1309 let expected: Vec<u8> = vec![
1310 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32, 0xED, 0xCB, 0xA9, 0x87, 0x65, 0x43, 0x21,
1311 0x0F,
1312 ];
1313
1314 assert_eq!(encoded.as_slice(), expected);
1315
1316 let key = ColumnPropertyKey::decode(&encoded).unwrap();
1317 assert_eq!(key.column, 0xABCD);
1318 assert_eq!(key.property, 0x123456789ABCDEF0);
1319 }
1320
1321 #[test]
1322 fn test_order_preserving() {
1323 let key1 = ColumnPropertyKey {
1324 column: ColumnId(1),
1325 property: ColumnPropertyId(100),
1326 };
1327 let key2 = ColumnPropertyKey {
1328 column: ColumnId(1),
1329 property: ColumnPropertyId(200),
1330 };
1331 let key3 = ColumnPropertyKey {
1332 column: ColumnId(2),
1333 property: ColumnPropertyId(0),
1334 };
1335
1336 let encoded1 = key1.encode();
1337 let encoded2 = key2.encode();
1338 let encoded3 = key3.encode();
1339
1340 assert!(encoded3 < encoded2, "ordering not preserved");
1341 assert!(encoded2 < encoded1, "ordering not preserved");
1342 }
1343}
1344
1345#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
1346#[key(tag = Handler)]
1347pub struct HandlerKey {
1348 pub handler: HandlerId,
1349}
1350
1351impl HandlerKey {
1352 pub fn new(handler: HandlerId) -> Self {
1353 Self {
1354 handler,
1355 }
1356 }
1357
1358 pub fn encoded(handler: impl Into<HandlerId>) -> EncodedKey {
1359 Self::new(handler.into()).encode()
1360 }
1361
1362 pub fn full_scan() -> TaggedKeyBoundRange {
1363 TaggedKeyBoundRange::kind(Self::TAG)
1364 }
1365}
1366
1367#[cfg(test)]
1368pub mod handler_key_tests {
1369 use super::HandlerKey;
1370 use crate::interface::catalog::id::HandlerId;
1371
1372 #[test]
1373 fn test_encode_decode() {
1374 let key = HandlerKey {
1375 handler: HandlerId(0xABCD),
1376 };
1377 let encoded = key.encode();
1378 let expected = vec![0xD4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32];
1379 assert_eq!(encoded.as_slice(), expected);
1380
1381 let decoded = HandlerKey::decode(&encoded).unwrap();
1382 assert_eq!(decoded.handler, HandlerId(0xABCD));
1383 }
1384
1385 #[test]
1386 fn test_order_preserving() {
1387 let key1 = HandlerKey {
1388 handler: HandlerId(1),
1389 };
1390 let key2 = HandlerKey {
1391 handler: HandlerId(2),
1392 };
1393
1394 let encoded1 = key1.encode();
1395 let encoded2 = key2.encode();
1396
1397 assert!(encoded2 < encoded1, "ordering not preserved");
1398 }
1399}
1400
1401#[cfg(test)]
1402mod verify_byte_identical_handler_key {
1403 use reifydb_codec::key::serializer::KeySerializer;
1404
1405 use super::HandlerKey;
1406 use crate::interface::catalog::id::HandlerId;
1407
1408 fn legacy_encode(key: &HandlerKey) -> Vec<u8> {
1409 let mut serializer = KeySerializer::with_capacity(9);
1410 serializer.extend_u8(HandlerKey::TAG as u8).extend_u64(key.handler);
1411 serializer.to_encoded_key().as_slice().to_vec()
1412 }
1413
1414 #[test]
1415 fn matches_legacy_byte_layout() {
1416 for handler in [0u64, 1, 42, 0xABCD, u64::MAX] {
1417 let key = HandlerKey {
1418 handler: HandlerId(handler),
1419 };
1420 assert_eq!(legacy_encode(&key), key.encode().as_slice().to_vec(), "handler={handler:#x}");
1421 }
1422 }
1423}
1424
1425#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
1426#[key(tag = VariantHandler)]
1427pub struct VariantHandlerKey {
1428 pub namespace: NamespaceId,
1429 pub sumtype: SumTypeId,
1430 pub variant_tag: u8,
1431 pub handler: HandlerId,
1432}
1433
1434impl VariantHandlerKey {
1435 pub fn new(namespace: NamespaceId, sumtype: SumTypeId, variant_tag: u8, handler: HandlerId) -> Self {
1436 Self {
1437 namespace,
1438 sumtype,
1439 variant_tag,
1440 handler,
1441 }
1442 }
1443
1444 pub fn encoded(
1445 namespace: impl Into<NamespaceId>,
1446 sumtype: impl Into<SumTypeId>,
1447 variant_tag: u8,
1448 handler: impl Into<HandlerId>,
1449 ) -> EncodedKey {
1450 Self::new(namespace.into(), sumtype.into(), variant_tag, handler.into()).encode()
1451 }
1452
1453 pub fn variant_scan(namespace: NamespaceId, sumtype: SumTypeId, variant_tag: u8) -> TaggedKeyBoundRange {
1454 TaggedKeyBoundRange::prefix(
1455 Self::TAG,
1456 [
1457 Field::UDesc(Width::U64, namespace.0 as u128),
1458 Field::UDesc(Width::U64, sumtype.0 as u128),
1459 Field::UDesc(Width::U8, variant_tag as u128),
1460 ],
1461 )
1462 }
1463}
1464
1465#[cfg(test)]
1466pub mod variant_handler_key_tests {
1467 use std::ops::Bound;
1468
1469 use reifydb_value::value::sumtype::SumTypeId;
1470
1471 use super::VariantHandlerKey;
1472 use crate::interface::catalog::id::{HandlerId, NamespaceId};
1473
1474 #[test]
1475 fn test_encode_decode() {
1476 let key = VariantHandlerKey {
1477 namespace: NamespaceId(0xABCD),
1478 sumtype: SumTypeId(0x1234),
1479 variant_tag: 5,
1480 handler: HandlerId(0x6789),
1481 };
1482 let encoded = key.encode();
1483 let expected: Vec<u8> = vec![
1484 0xD2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED,
1485 0xCB, 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x98, 0x76,
1486 ];
1487 assert_eq!(encoded.as_slice(), expected);
1488
1489 let decoded = VariantHandlerKey::decode(&encoded).unwrap();
1490 assert_eq!(decoded.namespace, NamespaceId(0xABCD));
1491 assert_eq!(decoded.sumtype, SumTypeId(0x1234));
1492 assert_eq!(decoded.variant_tag, 5);
1493 assert_eq!(decoded.handler, HandlerId(0x6789));
1494 }
1495
1496 #[test]
1497 fn test_order_preserving() {
1498 let key1 = VariantHandlerKey {
1499 namespace: NamespaceId::SYSTEM,
1500 sumtype: SumTypeId(5),
1501 variant_tag: 3,
1502 handler: HandlerId(100),
1503 };
1504 let key2 = VariantHandlerKey {
1505 namespace: NamespaceId::SYSTEM,
1506 sumtype: SumTypeId(5),
1507 variant_tag: 3,
1508 handler: HandlerId(200),
1509 };
1510 let key3 = VariantHandlerKey {
1511 namespace: NamespaceId::SYSTEM,
1512 sumtype: SumTypeId(5),
1513 variant_tag: 4,
1514 handler: HandlerId(1),
1515 };
1516 let key4 = VariantHandlerKey {
1517 namespace: NamespaceId::DEFAULT,
1518 sumtype: SumTypeId(1),
1519 variant_tag: 0,
1520 handler: HandlerId(1),
1521 };
1522
1523 let encoded1 = key1.encode();
1524 let encoded2 = key2.encode();
1525 let encoded3 = key3.encode();
1526 let encoded4 = key4.encode();
1527
1528 assert!(encoded4 < encoded3, "ordering not preserved");
1529 assert!(encoded3 < encoded2, "ordering not preserved");
1530 assert!(encoded2 < encoded1, "ordering not preserved");
1531 }
1532
1533 #[test]
1534 fn test_variant_scan() {
1535 let ns = NamespaceId::SYSTEM;
1536 let st = SumTypeId(10);
1537 let tag = 5u8;
1538
1539 let range = VariantHandlerKey::variant_scan(ns, st, tag).encode();
1540 let start = match &range.start {
1541 Bound::Included(k) | Bound::Excluded(k) => k,
1542 Bound::Unbounded => panic!("expected bounded start"),
1543 };
1544 let end = match &range.end {
1545 Bound::Included(k) | Bound::Excluded(k) => k,
1546 Bound::Unbounded => panic!("expected bounded end"),
1547 };
1548
1549 let key = VariantHandlerKey {
1550 namespace: ns,
1551 sumtype: st,
1552 variant_tag: tag,
1553 handler: HandlerId(42),
1554 };
1555 let encoded = key.encode();
1556 assert!(encoded.as_slice() >= start.as_slice());
1557 assert!(encoded.as_slice() <= end.as_slice());
1558
1559 let other = VariantHandlerKey {
1560 namespace: ns,
1561 sumtype: st,
1562 variant_tag: tag + 1,
1563 handler: HandlerId(42),
1564 };
1565 let other_encoded = other.encode();
1566 assert!(other_encoded.as_slice() < start.as_slice());
1567 }
1568}
1569
1570#[cfg(test)]
1571mod verify_byte_identical_variant_handler_key {
1572 use reifydb_codec::key::serializer::KeySerializer;
1573 use reifydb_value::value::sumtype::SumTypeId;
1574
1575 use super::VariantHandlerKey;
1576 use crate::interface::catalog::id::{HandlerId, NamespaceId};
1577
1578 fn legacy_encode(key: &VariantHandlerKey) -> Vec<u8> {
1579 let mut serializer = KeySerializer::with_capacity(26);
1580 serializer
1581 .extend_u8(VariantHandlerKey::TAG as u8)
1582 .extend_u64(key.namespace)
1583 .extend_u64(key.sumtype)
1584 .extend_u8(key.variant_tag)
1585 .extend_u64(key.handler);
1586 serializer.to_encoded_key().as_slice().to_vec()
1587 }
1588
1589 #[test]
1590 fn matches_legacy_byte_layout() {
1591 for (namespace, sumtype, variant_tag, handler) in [
1592 (0u64, 0u64, 0u8, 0u64),
1593 (1, 2, 3, 4),
1594 (0xABCD, 0x1234, 5, 0x6789),
1595 (u64::MAX, u64::MAX, u8::MAX, u64::MAX),
1596 ] {
1597 let key = VariantHandlerKey {
1598 namespace: NamespaceId(namespace),
1599 sumtype: SumTypeId(sumtype),
1600 variant_tag,
1601 handler: HandlerId(handler),
1602 };
1603 assert_eq!(
1604 legacy_encode(&key),
1605 key.encode().as_slice().to_vec(),
1606 "namespace={namespace:#x} sumtype={sumtype:#x} variant_tag={variant_tag:#x} handler={handler:#x}"
1607 );
1608 }
1609 }
1610}
1611
1612#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
1613#[key(tag = Binding)]
1614pub struct BindingKey {
1615 pub binding: BindingId,
1616}
1617
1618impl BindingKey {
1619 pub fn new(binding: impl Into<BindingId>) -> Self {
1620 Self {
1621 binding: binding.into(),
1622 }
1623 }
1624
1625 pub fn full_scan() -> TaggedKeyBoundRange {
1626 TaggedKeyBoundRange::kind(Self::TAG)
1627 }
1628}
1629
1630#[cfg(test)]
1631pub mod binding_key_tests {
1632 use super::BindingKey;
1633 use crate::interface::catalog::id::BindingId;
1634
1635 #[test]
1636 fn test_encode_decode() {
1637 let key = BindingKey {
1638 binding: BindingId(0xABCD),
1639 };
1640 let encoded = key.encode();
1641 let decoded = BindingKey::decode(&encoded).unwrap();
1642 assert_eq!(decoded.binding, 0xABCD);
1643 }
1644}
1645
1646#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
1647#[key(tag = PrimaryKey)]
1648pub struct PrimaryKeyKey {
1649 pub primary_key: PrimaryKeyId,
1650}
1651
1652impl PrimaryKeyKey {
1653 pub fn new(primary_key: impl Into<PrimaryKeyId>) -> Self {
1654 Self {
1655 primary_key: primary_key.into(),
1656 }
1657 }
1658
1659 pub fn encoded(primary_key: impl Into<PrimaryKeyId>) -> EncodedKey {
1660 Self::new(primary_key).encode()
1661 }
1662
1663 pub fn full_scan() -> TaggedKeyBoundRange {
1664 TaggedKeyBoundRange::kind(Self::TAG)
1665 }
1666}
1667
1668#[cfg(test)]
1669mod primary_key_key_tests {
1670 use super::PrimaryKeyKey;
1671 use crate::interface::catalog::id::PrimaryKeyId;
1672
1673 #[test]
1674 fn test_encode_decode() {
1675 let key = PrimaryKeyKey {
1676 primary_key: PrimaryKeyId(0xABCD),
1677 };
1678 let encoded = key.encode();
1679 let decoded = PrimaryKeyKey::decode(&encoded).unwrap();
1680 assert_eq!(decoded.primary_key, PrimaryKeyId(0xABCD));
1681 }
1682}