Skip to main content

reifydb_core/key/
any.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use std::{borrow::Cow, cmp::Ordering};
5
6use reifydb_codec::key::{encode_bytes, encode_u128_varint, encoded::EncodedKey, serializer::KeySerializer};
7use reifydb_value::value::Value;
8use smallvec::SmallVec;
9
10use crate::{
11	interface::{
12		catalog::{id::IndexId, metrics::MetricsId, object::ObjectId},
13		store::Tier,
14	},
15	key::{
16		catalog::{
17			BindingKey, ColumnPropertyKey, DictionaryEntryIndexKey, DictionaryEntryKey, DictionaryKey,
18			HandlerKey, IndexEntryKey, IndexKey, PrimaryKeyKey, RelationshipKey, SinkKey, SourceKey,
19			SumTypeKey, TableKey, VariantHandlerKey, ViewKey,
20		},
21		cdc::CdcConsumerKey,
22		column::{
23			ColumnKey, ColumnSequenceKey, ColumnSnapshotKey, ColumnsKey, SeriesColumnSnapshotKey,
24			TableColumnSnapshotKey,
25		},
26		config::ConfigStorageKey,
27		flow::{FlowEdgeByFlowKey, FlowEdgeKey, FlowKey, FlowVersionKey},
28		identity::{
29			AuthenticationKey, GrantedRoleKey, IdentityAttributeKey, IdentityAttributeValueKey,
30			IdentityKey, PolicyKey, PolicyOpKey, RoleKey, TokenKey,
31		},
32		metric::{MetricCdcKey, MetricStorageKey},
33		namespace::{
34			NamespaceBindingKey, NamespaceDictionaryKey, NamespaceFlowKey, NamespaceHandlerKey,
35			NamespaceKey, NamespaceProcedureKey, NamespaceQueueKey, NamespaceRingBufferKey,
36			NamespaceSeriesKey, NamespaceSinkKey, NamespaceSourceKey, NamespaceSumTypeKey,
37			NamespaceTableKey, NamespaceViewKey,
38		},
39		operator::{
40			key::{OperatorByFlowKey, OperatorKey},
41			state::OperatorStateKey,
42		},
43		operator_settings::OperatorSettingsKey,
44		output_frontier::OutputFrontierKey,
45		partition::PartitionKey,
46		procedure::{ProcedureKey, ProcedureParamKey},
47		queue::{
48			QueueAttemptKey, QueueDeduplicationKey, QueueDueKey, QueueItemStateKey, QueueKey,
49			QueueKeyActiveKey, QueuePartitionKey,
50		},
51		ringbuffer::{RingBufferKey, RingBufferMetadataKey},
52		row::{
53			PartitionedRowKey, PartitionedSortedViewRowKey, RowKey, RowSequenceKey, RowSettingsKey,
54			RowShapeFieldKey, RowShapeKey, SortedViewRowKey, encode_sort_run,
55		},
56		series::{PartitionedSeriesRowKey, SeriesKey, SeriesMetadataKey, SeriesRowKey},
57		system::{
58			MigrationEventKey, MigrationKey, SystemSequenceKey, SystemVersionKey, TransactionVersionKey,
59			VersionEpochKey,
60		},
61		tag::KeyTag,
62	},
63};
64
65#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
66pub enum MetricKey {
67	Cdc(MetricCdcKey),
68	Storage(MetricStorageKey),
69}
70
71#[derive(Debug, Clone, PartialEq, Hash)]
72pub enum TaggedKey {
73	Namespace(NamespaceKey),
74	Table(TableKey),
75	Row(RowKey),
76	NamespaceTable(NamespaceTableKey),
77	SystemSequence(SystemSequenceKey),
78	Columns(ColumnsKey),
79	Column(ColumnKey),
80	RowSequence(RowSequenceKey),
81	ColumnProperty(ColumnPropertyKey),
82	SystemVersion(SystemVersionKey),
83	TransactionVersion(TransactionVersionKey),
84	Index(IndexKey),
85	IndexEntry(IndexEntryKey),
86	ColumnSequence(ColumnSequenceKey),
87	CdcConsumer(CdcConsumerKey),
88	View(ViewKey),
89	NamespaceView(NamespaceViewKey),
90	PrimaryKey(PrimaryKeyKey),
91	OperatorState(OperatorStateKey),
92	RingBuffer(RingBufferKey),
93	NamespaceRingBuffer(NamespaceRingBufferKey),
94	RingBufferMetadata(RingBufferMetadataKey),
95	Flow(FlowKey),
96	NamespaceFlow(NamespaceFlowKey),
97	Operator(OperatorKey),
98	OperatorByFlow(OperatorByFlowKey),
99	FlowEdge(FlowEdgeKey),
100	FlowEdgeByFlow(FlowEdgeByFlowKey),
101	OutputFrontier(OutputFrontierKey),
102	Dictionary(DictionaryKey),
103	DictionaryEntry(DictionaryEntryKey),
104	DictionaryEntryIndex(DictionaryEntryIndexKey),
105	NamespaceDictionary(NamespaceDictionaryKey),
106	Metric(MetricKey),
107	FlowVersion(FlowVersionKey),
108	RowShape(RowShapeKey),
109	RowShapeField(RowShapeFieldKey),
110	SumType(SumTypeKey),
111	NamespaceSumType(NamespaceSumTypeKey),
112	Handler(HandlerKey),
113	NamespaceHandler(NamespaceHandlerKey),
114	VariantHandler(VariantHandlerKey),
115	Series(SeriesKey),
116	NamespaceSeries(NamespaceSeriesKey),
117	SeriesMetadata(SeriesMetadataKey),
118	Identity(IdentityKey),
119	Role(RoleKey),
120	GrantedRole(GrantedRoleKey),
121	Policy(PolicyKey),
122	PolicyOp(PolicyOpKey),
123	Migration(MigrationKey),
124	MigrationEvent(MigrationEventKey),
125	Authentication(AuthenticationKey),
126	ConfigStorage(ConfigStorageKey),
127	Token(TokenKey),
128	Source(SourceKey),
129	NamespaceSource(NamespaceSourceKey),
130	Sink(SinkKey),
131	NamespaceSink(NamespaceSinkKey),
132	RowSettings(RowSettingsKey),
133	Procedure(ProcedureKey),
134	NamespaceProcedure(NamespaceProcedureKey),
135	ProcedureParam(ProcedureParamKey),
136	Binding(BindingKey),
137	NamespaceBinding(NamespaceBindingKey),
138	OperatorSettings(OperatorSettingsKey),
139	ColumnSnapshot(ColumnSnapshotKey),
140	SeriesColumnSnapshot(SeriesColumnSnapshotKey),
141	TableColumnSnapshot(TableColumnSnapshotKey),
142	VersionEpoch(VersionEpochKey),
143	IdentityAttribute(IdentityAttributeKey),
144	IdentityAttributeValue(IdentityAttributeValueKey),
145	PartitionedRow(PartitionedRowKey),
146	Partition(PartitionKey),
147	Queue(QueueKey),
148	NamespaceQueue(NamespaceQueueKey),
149	QueueDeduplication(QueueDeduplicationKey),
150	Relationship(RelationshipKey),
151	SeriesRow(SeriesRowKey),
152	PartitionedSeriesRow(PartitionedSeriesRowKey),
153	QueuePartition(QueuePartitionKey),
154	QueueItemState(QueueItemStateKey),
155	QueueDue(QueueDueKey),
156	QueueAttempt(QueueAttemptKey),
157	QueueKeyActive(QueueKeyActiveKey),
158	SortedViewRow(SortedViewRowKey),
159	PartitionedSortedViewRow(PartitionedSortedViewRowKey),
160}
161
162impl TaggedKey {
163	pub fn kind(&self) -> KeyTag {
164		match self {
165			Self::Namespace(_) => KeyTag::Namespace,
166			Self::Table(_) => KeyTag::Table,
167			Self::Row(_) => KeyTag::Row,
168			Self::NamespaceTable(_) => KeyTag::NamespaceTable,
169			Self::SystemSequence(_) => KeyTag::SystemSequence,
170			Self::Columns(_) => KeyTag::Columns,
171			Self::Column(_) => KeyTag::Column,
172			Self::RowSequence(_) => KeyTag::RowSequence,
173			Self::ColumnProperty(_) => KeyTag::ColumnProperty,
174			Self::SystemVersion(_) => KeyTag::SystemVersion,
175			Self::TransactionVersion(_) => KeyTag::TransactionVersion,
176			Self::Index(_) => KeyTag::Index,
177			Self::IndexEntry(_) => KeyTag::IndexEntry,
178			Self::ColumnSequence(_) => KeyTag::ColumnSequence,
179			Self::CdcConsumer(_) => KeyTag::CdcConsumer,
180			Self::View(_) => KeyTag::View,
181			Self::NamespaceView(_) => KeyTag::NamespaceView,
182			Self::PrimaryKey(_) => KeyTag::PrimaryKey,
183			Self::OperatorState(_) => KeyTag::OperatorState,
184			Self::RingBuffer(_) => KeyTag::RingBuffer,
185			Self::NamespaceRingBuffer(_) => KeyTag::NamespaceRingBuffer,
186			Self::RingBufferMetadata(_) => KeyTag::RingBufferMetadata,
187			Self::Flow(_) => KeyTag::Flow,
188			Self::NamespaceFlow(_) => KeyTag::NamespaceFlow,
189			Self::Operator(_) => KeyTag::Operator,
190			Self::OperatorByFlow(_) => KeyTag::OperatorByFlow,
191			Self::FlowEdge(_) => KeyTag::FlowEdge,
192			Self::FlowEdgeByFlow(_) => KeyTag::FlowEdgeByFlow,
193			Self::OutputFrontier(_) => KeyTag::OutputFrontier,
194			Self::Dictionary(_) => KeyTag::Dictionary,
195			Self::DictionaryEntry(_) => KeyTag::DictionaryEntry,
196			Self::DictionaryEntryIndex(_) => KeyTag::DictionaryEntryIndex,
197			Self::NamespaceDictionary(_) => KeyTag::NamespaceDictionary,
198			Self::Metric(_) => KeyTag::Metric,
199			Self::FlowVersion(_) => KeyTag::FlowVersion,
200			Self::RowShape(_) => KeyTag::RowShape,
201			Self::RowShapeField(_) => KeyTag::RowShapeField,
202			Self::SumType(_) => KeyTag::SumType,
203			Self::NamespaceSumType(_) => KeyTag::NamespaceSumType,
204			Self::Handler(_) => KeyTag::Handler,
205			Self::NamespaceHandler(_) => KeyTag::NamespaceHandler,
206			Self::VariantHandler(_) => KeyTag::VariantHandler,
207			Self::Series(_) => KeyTag::Series,
208			Self::NamespaceSeries(_) => KeyTag::NamespaceSeries,
209			Self::SeriesMetadata(_) => KeyTag::SeriesMetadata,
210			Self::Identity(_) => KeyTag::Identity,
211			Self::Role(_) => KeyTag::Role,
212			Self::GrantedRole(_) => KeyTag::GrantedRole,
213			Self::Policy(_) => KeyTag::Policy,
214			Self::PolicyOp(_) => KeyTag::PolicyOp,
215			Self::Migration(_) => KeyTag::Migration,
216			Self::MigrationEvent(_) => KeyTag::MigrationEvent,
217			Self::Authentication(_) => KeyTag::Authentication,
218			Self::ConfigStorage(_) => KeyTag::ConfigStorage,
219			Self::Token(_) => KeyTag::Token,
220			Self::Source(_) => KeyTag::Source,
221			Self::NamespaceSource(_) => KeyTag::NamespaceSource,
222			Self::Sink(_) => KeyTag::Sink,
223			Self::NamespaceSink(_) => KeyTag::NamespaceSink,
224			Self::RowSettings(_) => KeyTag::RowSettings,
225			Self::Procedure(_) => KeyTag::Procedure,
226			Self::NamespaceProcedure(_) => KeyTag::NamespaceProcedure,
227			Self::ProcedureParam(_) => KeyTag::ProcedureParam,
228			Self::Binding(_) => KeyTag::Binding,
229			Self::NamespaceBinding(_) => KeyTag::NamespaceBinding,
230			Self::OperatorSettings(_) => KeyTag::OperatorSettings,
231			Self::ColumnSnapshot(_) => KeyTag::ColumnSnapshot,
232			Self::SeriesColumnSnapshot(_) => KeyTag::SeriesColumnSnapshot,
233			Self::TableColumnSnapshot(_) => KeyTag::TableColumnSnapshot,
234			Self::VersionEpoch(_) => KeyTag::VersionEpoch,
235			Self::IdentityAttribute(_) => KeyTag::IdentityAttribute,
236			Self::IdentityAttributeValue(_) => KeyTag::IdentityAttributeValue,
237			Self::PartitionedRow(_) => KeyTag::PartitionedRow,
238			Self::Partition(_) => KeyTag::Partition,
239			Self::Queue(_) => KeyTag::Queue,
240			Self::NamespaceQueue(_) => KeyTag::NamespaceQueue,
241			Self::QueueDeduplication(_) => KeyTag::QueueDeduplication,
242			Self::Relationship(_) => KeyTag::Relationship,
243			Self::SeriesRow(_) => KeyTag::SeriesRow,
244			Self::PartitionedSeriesRow(_) => KeyTag::PartitionedSeriesRow,
245			Self::QueuePartition(_) => KeyTag::QueuePartition,
246			Self::QueueItemState(_) => KeyTag::QueueItemState,
247			Self::QueueDue(_) => KeyTag::QueueDue,
248			Self::QueueAttempt(_) => KeyTag::QueueAttempt,
249			Self::QueueKeyActive(_) => KeyTag::QueueKeyActive,
250			Self::SortedViewRow(_) => KeyTag::SortedViewRow,
251			Self::PartitionedSortedViewRow(_) => KeyTag::PartitionedSortedViewRow,
252		}
253	}
254
255	pub fn encode(&self) -> EncodedKey {
256		match self {
257			Self::Namespace(key) => key.encode(),
258			Self::Table(key) => key.encode(),
259			Self::Row(key) => key.encode(),
260			Self::NamespaceTable(key) => key.encode(),
261			Self::SystemSequence(key) => key.encode(),
262			Self::Columns(key) => key.encode(),
263			Self::Column(key) => key.encode(),
264			Self::RowSequence(key) => key.encode(),
265			Self::ColumnProperty(key) => key.encode(),
266			Self::SystemVersion(key) => key.encode(),
267			Self::TransactionVersion(key) => key.encode(),
268			Self::Index(key) => key.encode(),
269			Self::IndexEntry(key) => key.encode(),
270			Self::ColumnSequence(key) => key.encode(),
271			Self::CdcConsumer(key) => key.encode(),
272			Self::View(key) => key.encode(),
273			Self::NamespaceView(key) => key.encode(),
274			Self::PrimaryKey(key) => key.encode(),
275			Self::OperatorState(key) => key.encode(),
276			Self::RingBuffer(key) => key.encode(),
277			Self::NamespaceRingBuffer(key) => key.encode(),
278			Self::RingBufferMetadata(key) => key.encode(),
279			Self::Flow(key) => key.encode(),
280			Self::NamespaceFlow(key) => key.encode(),
281			Self::Operator(key) => key.encode(),
282			Self::OperatorByFlow(key) => key.encode(),
283			Self::FlowEdge(key) => key.encode(),
284			Self::FlowEdgeByFlow(key) => key.encode(),
285			Self::OutputFrontier(key) => key.encode(),
286			Self::Dictionary(key) => key.encode(),
287			Self::DictionaryEntry(key) => key.encode(),
288			Self::DictionaryEntryIndex(key) => key.encode(),
289			Self::NamespaceDictionary(key) => key.encode(),
290			Self::Metric(MetricKey::Cdc(key)) => key.encode(),
291			Self::Metric(MetricKey::Storage(key)) => key.encode(),
292			Self::FlowVersion(key) => key.encode(),
293			Self::RowShape(key) => key.encode(),
294			Self::RowShapeField(key) => key.encode(),
295			Self::SumType(key) => key.encode(),
296			Self::NamespaceSumType(key) => key.encode(),
297			Self::Handler(key) => key.encode(),
298			Self::NamespaceHandler(key) => key.encode(),
299			Self::VariantHandler(key) => key.encode(),
300			Self::Series(key) => key.encode(),
301			Self::NamespaceSeries(key) => key.encode(),
302			Self::SeriesMetadata(key) => key.encode(),
303			Self::Identity(key) => key.encode(),
304			Self::Role(key) => key.encode(),
305			Self::GrantedRole(key) => key.encode(),
306			Self::Policy(key) => key.encode(),
307			Self::PolicyOp(key) => key.encode(),
308			Self::Migration(key) => key.encode(),
309			Self::MigrationEvent(key) => key.encode(),
310			Self::Authentication(key) => key.encode(),
311			Self::ConfigStorage(key) => key.encode(),
312			Self::Token(key) => key.encode(),
313			Self::Source(key) => key.encode(),
314			Self::NamespaceSource(key) => key.encode(),
315			Self::Sink(key) => key.encode(),
316			Self::NamespaceSink(key) => key.encode(),
317			Self::RowSettings(key) => key.encode(),
318			Self::Procedure(key) => key.encode(),
319			Self::NamespaceProcedure(key) => key.encode(),
320			Self::ProcedureParam(key) => key.encode(),
321			Self::Binding(key) => key.encode(),
322			Self::NamespaceBinding(key) => key.encode(),
323			Self::OperatorSettings(key) => key.encode(),
324			Self::ColumnSnapshot(key) => key.encode(),
325			Self::SeriesColumnSnapshot(key) => key.encode(),
326			Self::TableColumnSnapshot(key) => key.encode(),
327			Self::VersionEpoch(key) => key.encode(),
328			Self::IdentityAttribute(key) => key.encode(),
329			Self::IdentityAttributeValue(key) => key.encode(),
330			Self::PartitionedRow(key) => key.encode(),
331			Self::Partition(key) => key.encode(),
332			Self::Queue(key) => key.encode(),
333			Self::NamespaceQueue(key) => key.encode(),
334			Self::QueueDeduplication(key) => key.encode(),
335			Self::Relationship(key) => key.encode(),
336			Self::SeriesRow(key) => key.encode(),
337			Self::PartitionedSeriesRow(key) => key.encode(),
338			Self::QueuePartition(key) => key.encode(),
339			Self::QueueItemState(key) => key.encode(),
340			Self::QueueDue(key) => key.encode(),
341			Self::QueueAttempt(key) => key.encode(),
342			Self::QueueKeyActive(key) => key.encode(),
343			Self::SortedViewRow(key) => key.encode(),
344			Self::PartitionedSortedViewRow(key) => key.encode(),
345		}
346	}
347
348	pub fn decode(key: &EncodedKey) -> Option<Self> {
349		match KeyTag::of(key)? {
350			KeyTag::Namespace => NamespaceKey::decode(key).map(Self::Namespace),
351			KeyTag::Table => TableKey::decode(key).map(Self::Table),
352			KeyTag::Row => RowKey::decode(key).map(Self::Row),
353			KeyTag::NamespaceTable => NamespaceTableKey::decode(key).map(Self::NamespaceTable),
354			KeyTag::SystemSequence => SystemSequenceKey::decode(key).map(Self::SystemSequence),
355			KeyTag::Columns => ColumnsKey::decode(key).map(Self::Columns),
356			KeyTag::Column => ColumnKey::decode(key).map(Self::Column),
357			KeyTag::RowSequence => RowSequenceKey::decode(key).map(Self::RowSequence),
358			KeyTag::ColumnProperty => ColumnPropertyKey::decode(key).map(Self::ColumnProperty),
359			KeyTag::SystemVersion => SystemVersionKey::decode(key).map(Self::SystemVersion),
360			KeyTag::TransactionVersion => TransactionVersionKey::decode(key).map(Self::TransactionVersion),
361			KeyTag::Index => IndexKey::decode(key).map(Self::Index),
362			KeyTag::IndexEntry => IndexEntryKey::decode(key).map(Self::IndexEntry),
363			KeyTag::ColumnSequence => ColumnSequenceKey::decode(key).map(Self::ColumnSequence),
364			KeyTag::CdcConsumer => CdcConsumerKey::decode(key).map(Self::CdcConsumer),
365			KeyTag::View => ViewKey::decode(key).map(Self::View),
366			KeyTag::NamespaceView => NamespaceViewKey::decode(key).map(Self::NamespaceView),
367			KeyTag::PrimaryKey => PrimaryKeyKey::decode(key).map(Self::PrimaryKey),
368			KeyTag::OperatorState => OperatorStateKey::decode(key).map(Self::OperatorState),
369			KeyTag::RingBuffer => RingBufferKey::decode(key).map(Self::RingBuffer),
370			KeyTag::NamespaceRingBuffer => {
371				NamespaceRingBufferKey::decode(key).map(Self::NamespaceRingBuffer)
372			}
373			KeyTag::RingBufferMetadata => RingBufferMetadataKey::decode(key).map(Self::RingBufferMetadata),
374			KeyTag::Flow => FlowKey::decode(key).map(Self::Flow),
375			KeyTag::NamespaceFlow => NamespaceFlowKey::decode(key).map(Self::NamespaceFlow),
376			KeyTag::Operator => OperatorKey::decode(key).map(Self::Operator),
377			KeyTag::OperatorByFlow => OperatorByFlowKey::decode(key).map(Self::OperatorByFlow),
378			KeyTag::FlowEdge => FlowEdgeKey::decode(key).map(Self::FlowEdge),
379			KeyTag::FlowEdgeByFlow => FlowEdgeByFlowKey::decode(key).map(Self::FlowEdgeByFlow),
380			KeyTag::OutputFrontier => OutputFrontierKey::decode(key).map(Self::OutputFrontier),
381			KeyTag::Dictionary => DictionaryKey::decode(key).map(Self::Dictionary),
382			KeyTag::DictionaryEntry => DictionaryEntryKey::decode(key).map(Self::DictionaryEntry),
383			KeyTag::DictionaryEntryIndex => {
384				DictionaryEntryIndexKey::decode(key).map(Self::DictionaryEntryIndex)
385			}
386			KeyTag::NamespaceDictionary => {
387				NamespaceDictionaryKey::decode(key).map(Self::NamespaceDictionary)
388			}
389			KeyTag::Metric => decode_metric(key),
390			KeyTag::FlowVersion => FlowVersionKey::decode(key).map(Self::FlowVersion),
391			KeyTag::RowShape => RowShapeKey::decode(key).map(Self::RowShape),
392			KeyTag::RowShapeField => RowShapeFieldKey::decode(key).map(Self::RowShapeField),
393			KeyTag::SumType => SumTypeKey::decode(key).map(Self::SumType),
394			KeyTag::NamespaceSumType => NamespaceSumTypeKey::decode(key).map(Self::NamespaceSumType),
395			KeyTag::Handler => HandlerKey::decode(key).map(Self::Handler),
396			KeyTag::NamespaceHandler => NamespaceHandlerKey::decode(key).map(Self::NamespaceHandler),
397			KeyTag::VariantHandler => VariantHandlerKey::decode(key).map(Self::VariantHandler),
398			KeyTag::Series => SeriesKey::decode(key).map(Self::Series),
399			KeyTag::NamespaceSeries => NamespaceSeriesKey::decode(key).map(Self::NamespaceSeries),
400			KeyTag::SeriesMetadata => SeriesMetadataKey::decode(key).map(Self::SeriesMetadata),
401			KeyTag::Identity => IdentityKey::decode(key).map(Self::Identity),
402			KeyTag::Role => RoleKey::decode(key).map(Self::Role),
403			KeyTag::GrantedRole => GrantedRoleKey::decode(key).map(Self::GrantedRole),
404			KeyTag::Policy => PolicyKey::decode(key).map(Self::Policy),
405			KeyTag::PolicyOp => PolicyOpKey::decode(key).map(Self::PolicyOp),
406			KeyTag::Migration => MigrationKey::decode(key).map(Self::Migration),
407			KeyTag::MigrationEvent => MigrationEventKey::decode(key).map(Self::MigrationEvent),
408			KeyTag::Authentication => AuthenticationKey::decode(key).map(Self::Authentication),
409			KeyTag::ConfigStorage => ConfigStorageKey::decode(key).map(Self::ConfigStorage),
410			KeyTag::Token => TokenKey::decode(key).map(Self::Token),
411			KeyTag::Source => SourceKey::decode(key).map(Self::Source),
412			KeyTag::NamespaceSource => NamespaceSourceKey::decode(key).map(Self::NamespaceSource),
413			KeyTag::Sink => SinkKey::decode(key).map(Self::Sink),
414			KeyTag::NamespaceSink => NamespaceSinkKey::decode(key).map(Self::NamespaceSink),
415			KeyTag::RowSettings => RowSettingsKey::decode(key).map(Self::RowSettings),
416			KeyTag::Procedure => ProcedureKey::decode(key).map(Self::Procedure),
417			KeyTag::NamespaceProcedure => NamespaceProcedureKey::decode(key).map(Self::NamespaceProcedure),
418			KeyTag::ProcedureParam => ProcedureParamKey::decode(key).map(Self::ProcedureParam),
419			KeyTag::Binding => BindingKey::decode(key).map(Self::Binding),
420			KeyTag::NamespaceBinding => NamespaceBindingKey::decode(key).map(Self::NamespaceBinding),
421			KeyTag::OperatorSettings => OperatorSettingsKey::decode(key).map(Self::OperatorSettings),
422			KeyTag::ColumnSnapshot => ColumnSnapshotKey::decode(key).map(Self::ColumnSnapshot),
423			KeyTag::SeriesColumnSnapshot => {
424				SeriesColumnSnapshotKey::decode(key).map(Self::SeriesColumnSnapshot)
425			}
426			KeyTag::TableColumnSnapshot => {
427				TableColumnSnapshotKey::decode(key).map(Self::TableColumnSnapshot)
428			}
429			KeyTag::VersionEpoch => VersionEpochKey::decode(key).map(Self::VersionEpoch),
430			KeyTag::IdentityAttribute => IdentityAttributeKey::decode(key).map(Self::IdentityAttribute),
431			KeyTag::IdentityAttributeValue => {
432				IdentityAttributeValueKey::decode(key).map(Self::IdentityAttributeValue)
433			}
434			KeyTag::PartitionedRow => PartitionedRowKey::decode(key).map(Self::PartitionedRow),
435			KeyTag::Partition => PartitionKey::decode(key).map(Self::Partition),
436			KeyTag::Queue => QueueKey::decode(key).map(Self::Queue),
437			KeyTag::NamespaceQueue => NamespaceQueueKey::decode(key).map(Self::NamespaceQueue),
438			KeyTag::QueueDeduplication => QueueDeduplicationKey::decode(key).map(Self::QueueDeduplication),
439			KeyTag::Relationship => RelationshipKey::decode(key).map(Self::Relationship),
440			KeyTag::SeriesRow => SeriesRowKey::decode(key).map(Self::SeriesRow),
441			KeyTag::PartitionedSeriesRow => {
442				PartitionedSeriesRowKey::decode(key).map(Self::PartitionedSeriesRow)
443			}
444			KeyTag::QueuePartition => QueuePartitionKey::decode(key).map(Self::QueuePartition),
445			KeyTag::QueueItemState => QueueItemStateKey::decode(key).map(Self::QueueItemState),
446			KeyTag::QueueDue => QueueDueKey::decode(key).map(Self::QueueDue),
447			KeyTag::QueueAttempt => QueueAttemptKey::decode(key).map(Self::QueueAttempt),
448			KeyTag::QueueKeyActive => QueueKeyActiveKey::decode(key).map(Self::QueueKeyActive),
449			KeyTag::SortedViewRow => SortedViewRowKey::decode(key).map(Self::SortedViewRow),
450			KeyTag::PartitionedSortedViewRow => {
451				PartitionedSortedViewRowKey::decode(key).map(Self::PartitionedSortedViewRow)
452			}
453		}
454	}
455}
456
457fn decode_metric(key: &EncodedKey) -> Option<TaggedKey> {
458	MetricStorageKey::decode(key)
459		.map(MetricKey::Storage)
460		.or_else(|| MetricCdcKey::decode(key).map(MetricKey::Cdc))
461		.map(TaggedKey::Metric)
462}
463
464impl From<NamespaceKey> for TaggedKey {
465	fn from(key: NamespaceKey) -> Self {
466		Self::Namespace(key)
467	}
468}
469
470impl From<TableKey> for TaggedKey {
471	fn from(key: TableKey) -> Self {
472		Self::Table(key)
473	}
474}
475
476impl From<RowKey> for TaggedKey {
477	fn from(key: RowKey) -> Self {
478		Self::Row(key)
479	}
480}
481
482impl From<NamespaceTableKey> for TaggedKey {
483	fn from(key: NamespaceTableKey) -> Self {
484		Self::NamespaceTable(key)
485	}
486}
487
488impl From<SystemSequenceKey> for TaggedKey {
489	fn from(key: SystemSequenceKey) -> Self {
490		Self::SystemSequence(key)
491	}
492}
493
494impl From<ColumnsKey> for TaggedKey {
495	fn from(key: ColumnsKey) -> Self {
496		Self::Columns(key)
497	}
498}
499
500impl From<ColumnKey> for TaggedKey {
501	fn from(key: ColumnKey) -> Self {
502		Self::Column(key)
503	}
504}
505
506impl From<RowSequenceKey> for TaggedKey {
507	fn from(key: RowSequenceKey) -> Self {
508		Self::RowSequence(key)
509	}
510}
511
512impl From<ColumnPropertyKey> for TaggedKey {
513	fn from(key: ColumnPropertyKey) -> Self {
514		Self::ColumnProperty(key)
515	}
516}
517
518impl From<SystemVersionKey> for TaggedKey {
519	fn from(key: SystemVersionKey) -> Self {
520		Self::SystemVersion(key)
521	}
522}
523
524impl From<TransactionVersionKey> for TaggedKey {
525	fn from(key: TransactionVersionKey) -> Self {
526		Self::TransactionVersion(key)
527	}
528}
529
530impl From<IndexKey> for TaggedKey {
531	fn from(key: IndexKey) -> Self {
532		Self::Index(key)
533	}
534}
535
536impl From<IndexEntryKey> for TaggedKey {
537	fn from(key: IndexEntryKey) -> Self {
538		Self::IndexEntry(key)
539	}
540}
541
542impl From<ColumnSequenceKey> for TaggedKey {
543	fn from(key: ColumnSequenceKey) -> Self {
544		Self::ColumnSequence(key)
545	}
546}
547
548impl From<CdcConsumerKey> for TaggedKey {
549	fn from(key: CdcConsumerKey) -> Self {
550		Self::CdcConsumer(key)
551	}
552}
553
554impl From<ViewKey> for TaggedKey {
555	fn from(key: ViewKey) -> Self {
556		Self::View(key)
557	}
558}
559
560impl From<NamespaceViewKey> for TaggedKey {
561	fn from(key: NamespaceViewKey) -> Self {
562		Self::NamespaceView(key)
563	}
564}
565
566impl From<PrimaryKeyKey> for TaggedKey {
567	fn from(key: PrimaryKeyKey) -> Self {
568		Self::PrimaryKey(key)
569	}
570}
571
572impl From<OperatorStateKey> for TaggedKey {
573	fn from(key: OperatorStateKey) -> Self {
574		Self::OperatorState(key)
575	}
576}
577
578impl From<RingBufferKey> for TaggedKey {
579	fn from(key: RingBufferKey) -> Self {
580		Self::RingBuffer(key)
581	}
582}
583
584impl From<NamespaceRingBufferKey> for TaggedKey {
585	fn from(key: NamespaceRingBufferKey) -> Self {
586		Self::NamespaceRingBuffer(key)
587	}
588}
589
590impl From<RingBufferMetadataKey> for TaggedKey {
591	fn from(key: RingBufferMetadataKey) -> Self {
592		Self::RingBufferMetadata(key)
593	}
594}
595
596impl From<FlowKey> for TaggedKey {
597	fn from(key: FlowKey) -> Self {
598		Self::Flow(key)
599	}
600}
601
602impl From<NamespaceFlowKey> for TaggedKey {
603	fn from(key: NamespaceFlowKey) -> Self {
604		Self::NamespaceFlow(key)
605	}
606}
607
608impl From<OperatorKey> for TaggedKey {
609	fn from(key: OperatorKey) -> Self {
610		Self::Operator(key)
611	}
612}
613
614impl From<OperatorByFlowKey> for TaggedKey {
615	fn from(key: OperatorByFlowKey) -> Self {
616		Self::OperatorByFlow(key)
617	}
618}
619
620impl From<FlowEdgeKey> for TaggedKey {
621	fn from(key: FlowEdgeKey) -> Self {
622		Self::FlowEdge(key)
623	}
624}
625
626impl From<FlowEdgeByFlowKey> for TaggedKey {
627	fn from(key: FlowEdgeByFlowKey) -> Self {
628		Self::FlowEdgeByFlow(key)
629	}
630}
631
632impl From<OutputFrontierKey> for TaggedKey {
633	fn from(key: OutputFrontierKey) -> Self {
634		Self::OutputFrontier(key)
635	}
636}
637
638impl From<DictionaryKey> for TaggedKey {
639	fn from(key: DictionaryKey) -> Self {
640		Self::Dictionary(key)
641	}
642}
643
644impl From<DictionaryEntryKey> for TaggedKey {
645	fn from(key: DictionaryEntryKey) -> Self {
646		Self::DictionaryEntry(key)
647	}
648}
649
650impl From<DictionaryEntryIndexKey> for TaggedKey {
651	fn from(key: DictionaryEntryIndexKey) -> Self {
652		Self::DictionaryEntryIndex(key)
653	}
654}
655
656impl From<NamespaceDictionaryKey> for TaggedKey {
657	fn from(key: NamespaceDictionaryKey) -> Self {
658		Self::NamespaceDictionary(key)
659	}
660}
661
662impl From<FlowVersionKey> for TaggedKey {
663	fn from(key: FlowVersionKey) -> Self {
664		Self::FlowVersion(key)
665	}
666}
667
668impl From<RowShapeKey> for TaggedKey {
669	fn from(key: RowShapeKey) -> Self {
670		Self::RowShape(key)
671	}
672}
673
674impl From<RowShapeFieldKey> for TaggedKey {
675	fn from(key: RowShapeFieldKey) -> Self {
676		Self::RowShapeField(key)
677	}
678}
679
680impl From<SumTypeKey> for TaggedKey {
681	fn from(key: SumTypeKey) -> Self {
682		Self::SumType(key)
683	}
684}
685
686impl From<NamespaceSumTypeKey> for TaggedKey {
687	fn from(key: NamespaceSumTypeKey) -> Self {
688		Self::NamespaceSumType(key)
689	}
690}
691
692impl From<HandlerKey> for TaggedKey {
693	fn from(key: HandlerKey) -> Self {
694		Self::Handler(key)
695	}
696}
697
698impl From<NamespaceHandlerKey> for TaggedKey {
699	fn from(key: NamespaceHandlerKey) -> Self {
700		Self::NamespaceHandler(key)
701	}
702}
703
704impl From<VariantHandlerKey> for TaggedKey {
705	fn from(key: VariantHandlerKey) -> Self {
706		Self::VariantHandler(key)
707	}
708}
709
710impl From<SeriesKey> for TaggedKey {
711	fn from(key: SeriesKey) -> Self {
712		Self::Series(key)
713	}
714}
715
716impl From<NamespaceSeriesKey> for TaggedKey {
717	fn from(key: NamespaceSeriesKey) -> Self {
718		Self::NamespaceSeries(key)
719	}
720}
721
722impl From<SeriesMetadataKey> for TaggedKey {
723	fn from(key: SeriesMetadataKey) -> Self {
724		Self::SeriesMetadata(key)
725	}
726}
727
728impl From<IdentityKey> for TaggedKey {
729	fn from(key: IdentityKey) -> Self {
730		Self::Identity(key)
731	}
732}
733
734impl From<RoleKey> for TaggedKey {
735	fn from(key: RoleKey) -> Self {
736		Self::Role(key)
737	}
738}
739
740impl From<GrantedRoleKey> for TaggedKey {
741	fn from(key: GrantedRoleKey) -> Self {
742		Self::GrantedRole(key)
743	}
744}
745
746impl From<PolicyKey> for TaggedKey {
747	fn from(key: PolicyKey) -> Self {
748		Self::Policy(key)
749	}
750}
751
752impl From<PolicyOpKey> for TaggedKey {
753	fn from(key: PolicyOpKey) -> Self {
754		Self::PolicyOp(key)
755	}
756}
757
758impl From<MigrationKey> for TaggedKey {
759	fn from(key: MigrationKey) -> Self {
760		Self::Migration(key)
761	}
762}
763
764impl From<MigrationEventKey> for TaggedKey {
765	fn from(key: MigrationEventKey) -> Self {
766		Self::MigrationEvent(key)
767	}
768}
769
770impl From<AuthenticationKey> for TaggedKey {
771	fn from(key: AuthenticationKey) -> Self {
772		Self::Authentication(key)
773	}
774}
775
776impl From<ConfigStorageKey> for TaggedKey {
777	fn from(key: ConfigStorageKey) -> Self {
778		Self::ConfigStorage(key)
779	}
780}
781
782impl From<TokenKey> for TaggedKey {
783	fn from(key: TokenKey) -> Self {
784		Self::Token(key)
785	}
786}
787
788impl From<SourceKey> for TaggedKey {
789	fn from(key: SourceKey) -> Self {
790		Self::Source(key)
791	}
792}
793
794impl From<NamespaceSourceKey> for TaggedKey {
795	fn from(key: NamespaceSourceKey) -> Self {
796		Self::NamespaceSource(key)
797	}
798}
799
800impl From<SinkKey> for TaggedKey {
801	fn from(key: SinkKey) -> Self {
802		Self::Sink(key)
803	}
804}
805
806impl From<NamespaceSinkKey> for TaggedKey {
807	fn from(key: NamespaceSinkKey) -> Self {
808		Self::NamespaceSink(key)
809	}
810}
811
812impl From<RowSettingsKey> for TaggedKey {
813	fn from(key: RowSettingsKey) -> Self {
814		Self::RowSettings(key)
815	}
816}
817
818impl From<ProcedureKey> for TaggedKey {
819	fn from(key: ProcedureKey) -> Self {
820		Self::Procedure(key)
821	}
822}
823
824impl From<NamespaceProcedureKey> for TaggedKey {
825	fn from(key: NamespaceProcedureKey) -> Self {
826		Self::NamespaceProcedure(key)
827	}
828}
829
830impl From<ProcedureParamKey> for TaggedKey {
831	fn from(key: ProcedureParamKey) -> Self {
832		Self::ProcedureParam(key)
833	}
834}
835
836impl From<BindingKey> for TaggedKey {
837	fn from(key: BindingKey) -> Self {
838		Self::Binding(key)
839	}
840}
841
842impl From<NamespaceBindingKey> for TaggedKey {
843	fn from(key: NamespaceBindingKey) -> Self {
844		Self::NamespaceBinding(key)
845	}
846}
847
848impl From<OperatorSettingsKey> for TaggedKey {
849	fn from(key: OperatorSettingsKey) -> Self {
850		Self::OperatorSettings(key)
851	}
852}
853
854impl From<ColumnSnapshotKey> for TaggedKey {
855	fn from(key: ColumnSnapshotKey) -> Self {
856		Self::ColumnSnapshot(key)
857	}
858}
859
860impl From<SeriesColumnSnapshotKey> for TaggedKey {
861	fn from(key: SeriesColumnSnapshotKey) -> Self {
862		Self::SeriesColumnSnapshot(key)
863	}
864}
865
866impl From<TableColumnSnapshotKey> for TaggedKey {
867	fn from(key: TableColumnSnapshotKey) -> Self {
868		Self::TableColumnSnapshot(key)
869	}
870}
871
872impl From<VersionEpochKey> for TaggedKey {
873	fn from(key: VersionEpochKey) -> Self {
874		Self::VersionEpoch(key)
875	}
876}
877
878impl From<IdentityAttributeKey> for TaggedKey {
879	fn from(key: IdentityAttributeKey) -> Self {
880		Self::IdentityAttribute(key)
881	}
882}
883
884impl From<IdentityAttributeValueKey> for TaggedKey {
885	fn from(key: IdentityAttributeValueKey) -> Self {
886		Self::IdentityAttributeValue(key)
887	}
888}
889
890impl From<PartitionedRowKey> for TaggedKey {
891	fn from(key: PartitionedRowKey) -> Self {
892		Self::PartitionedRow(key)
893	}
894}
895
896impl From<PartitionKey> for TaggedKey {
897	fn from(key: PartitionKey) -> Self {
898		Self::Partition(key)
899	}
900}
901
902impl From<QueueKey> for TaggedKey {
903	fn from(key: QueueKey) -> Self {
904		Self::Queue(key)
905	}
906}
907
908impl From<NamespaceQueueKey> for TaggedKey {
909	fn from(key: NamespaceQueueKey) -> Self {
910		Self::NamespaceQueue(key)
911	}
912}
913
914impl From<QueueDeduplicationKey> for TaggedKey {
915	fn from(key: QueueDeduplicationKey) -> Self {
916		Self::QueueDeduplication(key)
917	}
918}
919
920impl From<RelationshipKey> for TaggedKey {
921	fn from(key: RelationshipKey) -> Self {
922		Self::Relationship(key)
923	}
924}
925
926impl From<SeriesRowKey> for TaggedKey {
927	fn from(key: SeriesRowKey) -> Self {
928		Self::SeriesRow(key)
929	}
930}
931
932impl From<PartitionedSeriesRowKey> for TaggedKey {
933	fn from(key: PartitionedSeriesRowKey) -> Self {
934		Self::PartitionedSeriesRow(key)
935	}
936}
937
938impl From<QueuePartitionKey> for TaggedKey {
939	fn from(key: QueuePartitionKey) -> Self {
940		Self::QueuePartition(key)
941	}
942}
943
944impl From<QueueItemStateKey> for TaggedKey {
945	fn from(key: QueueItemStateKey) -> Self {
946		Self::QueueItemState(key)
947	}
948}
949
950impl From<QueueDueKey> for TaggedKey {
951	fn from(key: QueueDueKey) -> Self {
952		Self::QueueDue(key)
953	}
954}
955
956impl From<QueueAttemptKey> for TaggedKey {
957	fn from(key: QueueAttemptKey) -> Self {
958		Self::QueueAttempt(key)
959	}
960}
961
962impl From<QueueKeyActiveKey> for TaggedKey {
963	fn from(key: QueueKeyActiveKey) -> Self {
964		Self::QueueKeyActive(key)
965	}
966}
967
968impl From<SortedViewRowKey> for TaggedKey {
969	fn from(key: SortedViewRowKey) -> Self {
970		Self::SortedViewRow(key)
971	}
972}
973
974impl From<PartitionedSortedViewRowKey> for TaggedKey {
975	fn from(key: PartitionedSortedViewRowKey) -> Self {
976		Self::PartitionedSortedViewRow(key)
977	}
978}
979
980impl From<MetricKey> for TaggedKey {
981	fn from(key: MetricKey) -> Self {
982		Self::Metric(key)
983	}
984}
985
986impl From<MetricStorageKey> for TaggedKey {
987	fn from(key: MetricStorageKey) -> Self {
988		Self::Metric(MetricKey::Storage(key))
989	}
990}
991
992impl From<MetricCdcKey> for TaggedKey {
993	fn from(key: MetricCdcKey) -> Self {
994		Self::Metric(MetricKey::Cdc(key))
995	}
996}
997
998fn desc<T: Ord + ?Sized>(left: &T, right: &T) -> Ordering {
999	right.cmp(left)
1000}
1001
1002fn object_cmp(left: &ObjectId, right: &ObjectId) -> Ordering {
1003	left.type_tag().cmp(&right.type_tag()).then_with(|| right.as_u64().cmp(&left.as_u64()))
1004}
1005
1006pub(crate) fn index_tag(index: &IndexId) -> u8 {
1007	match index {
1008		IndexId::Primary(_) => 0x01,
1009	}
1010}
1011
1012fn tier_byte(tier: Tier) -> u8 {
1013	match tier {
1014		Tier::Buffer => 0x00,
1015		Tier::Persistent => 0x01,
1016	}
1017}
1018
1019fn metrics_id_cmp(left: &MetricsId, right: &MetricsId) -> Ordering {
1020	match (left, right) {
1021		(MetricsId::System, MetricsId::System) => Ordering::Equal,
1022		(MetricsId::System, MetricsId::Object(_)) => Ordering::Less,
1023		(MetricsId::Object(_), MetricsId::System) => Ordering::Greater,
1024		(MetricsId::Object(left), MetricsId::Object(right)) => object_cmp(left, right),
1025	}
1026}
1027
1028pub(crate) fn encode_values(values: &[Value]) -> EncodedKey {
1029	let mut serializer = KeySerializer::new();
1030	for value in values {
1031		serializer.extend_value(value);
1032	}
1033	serializer.to_encoded_key()
1034}
1035
1036impl Ord for MetricKey {
1037	fn cmp(&self, other: &Self) -> Ordering {
1038		match (self, other) {
1039			(Self::Cdc(left), Self::Cdc(right)) => metrics_id_cmp(&left.id, &right.id),
1040			(Self::Cdc(_), Self::Storage(_)) => Ordering::Less,
1041			(Self::Storage(_), Self::Cdc(_)) => Ordering::Greater,
1042			(Self::Storage(left), Self::Storage(right)) => {
1043				desc(&tier_byte(left.tier), &tier_byte(right.tier))
1044					.then_with(|| metrics_id_cmp(&left.id, &right.id))
1045			}
1046		}
1047	}
1048}
1049
1050impl PartialOrd for MetricKey {
1051	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1052		Some(self.cmp(other))
1053	}
1054}
1055
1056impl Eq for TaggedKey {}
1057
1058#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1059pub enum Width {
1060	U8,
1061	U16,
1062	U32,
1063	U64,
1064	U128,
1065	Varint,
1066}
1067
1068impl Width {
1069	fn byte_len(self) -> usize {
1070		match self {
1071			Self::U8 => 1,
1072			Self::U16 => 2,
1073			Self::U32 => 4,
1074			Self::U64 => 8,
1075			Self::U128 => 16,
1076			Self::Varint => 0,
1077		}
1078	}
1079}
1080
1081#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1082pub enum ByteEncoding {
1083	Fixed,
1084	Escaped,
1085}
1086
1087#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1088pub enum RawEncoding {
1089	Verbatim,
1090	SortRun,
1091}
1092
1093#[derive(Debug, Clone)]
1094pub enum Field<'a> {
1095	UAsc(Width, u128),
1096	UDesc(Width, u128),
1097	BytesDesc(ByteEncoding, Cow<'a, [u8]>),
1098	RawAsc(RawEncoding, Cow<'a, [u8]>),
1099}
1100
1101impl Field<'_> {
1102	fn variant_rank(&self) -> u8 {
1103		match self {
1104			Self::UAsc(..) => 0,
1105			Self::UDesc(..) => 1,
1106			Self::BytesDesc(..) => 2,
1107			Self::RawAsc(..) => 3,
1108		}
1109	}
1110
1111	pub fn is_truncation_of(&self, other: &Self) -> bool {
1112		match (self, other) {
1113			(Self::RawAsc(RawEncoding::Verbatim, left), Self::RawAsc(RawEncoding::Verbatim, right)) => {
1114				left.len() < right.len() && right.starts_with(left)
1115			}
1116			_ => false,
1117		}
1118	}
1119
1120	pub fn encode(&self, out: &mut Vec<u8>) {
1121		match self {
1122			Self::UAsc(width, value) => {
1123				debug_assert!(
1124					!matches!(width, Width::Varint),
1125					"there is no ascending varint primitive in the key codec"
1126				);
1127				out.extend_from_slice(&value.to_be_bytes()[16 - width.byte_len()..]);
1128			}
1129			Self::UDesc(Width::Varint, value) => encode_u128_varint(*value, out),
1130			Self::UDesc(width, value) => {
1131				out.extend_from_slice(&(!*value).to_be_bytes()[16 - width.byte_len()..]);
1132			}
1133			Self::BytesDesc(ByteEncoding::Fixed, bytes) => out.extend(bytes.iter().map(|byte| !byte)),
1134			Self::BytesDesc(ByteEncoding::Escaped, bytes) => encode_bytes(bytes, out),
1135			Self::RawAsc(RawEncoding::Verbatim, bytes) => out.extend_from_slice(bytes),
1136			Self::RawAsc(RawEncoding::SortRun, bytes) => encode_sort_run(bytes, out),
1137		}
1138	}
1139}
1140
1141impl Ord for Field<'_> {
1142	fn cmp(&self, other: &Self) -> Ordering {
1143		match (self, other) {
1144			(Self::UAsc(_, left), Self::UAsc(_, right)) => left.cmp(right),
1145			(Self::UDesc(_, left), Self::UDesc(_, right)) => right.cmp(left),
1146			(Self::BytesDesc(_, left), Self::BytesDesc(_, right)) => right.as_ref().cmp(left.as_ref()),
1147			(Self::RawAsc(_, left), Self::RawAsc(_, right)) => left.as_ref().cmp(right.as_ref()),
1148			(left, right) => left.variant_rank().cmp(&right.variant_rank()),
1149		}
1150	}
1151}
1152
1153impl PartialOrd for Field<'_> {
1154	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1155		Some(self.cmp(other))
1156	}
1157}
1158
1159impl PartialEq for Field<'_> {
1160	fn eq(&self, other: &Self) -> bool {
1161		self.cmp(other) == Ordering::Equal
1162	}
1163}
1164
1165impl Eq for Field<'_> {}
1166
1167pub trait KeyFields {
1168	fn fields(&self) -> SmallVec<[Field<'_>; 6]>;
1169}
1170
1171impl KeyFields for MetricKey {
1172	fn fields(&self) -> SmallVec<[Field<'_>; 6]> {
1173		match self {
1174			Self::Cdc(key) => key.fields(),
1175			Self::Storage(key) => key.fields(),
1176		}
1177	}
1178}
1179
1180impl KeyFields for TaggedKey {
1181	fn fields(&self) -> SmallVec<[Field<'_>; 6]> {
1182		match self {
1183			Self::Namespace(key) => key.fields(),
1184			Self::Table(key) => key.fields(),
1185			Self::Row(key) => key.fields(),
1186			Self::NamespaceTable(key) => key.fields(),
1187			Self::SystemSequence(key) => key.fields(),
1188			Self::Columns(key) => key.fields(),
1189			Self::Column(key) => key.fields(),
1190			Self::RowSequence(key) => key.fields(),
1191			Self::ColumnProperty(key) => key.fields(),
1192			Self::SystemVersion(key) => key.fields(),
1193			Self::TransactionVersion(key) => key.fields(),
1194			Self::Index(key) => key.fields(),
1195			Self::IndexEntry(key) => key.fields(),
1196			Self::ColumnSequence(key) => key.fields(),
1197			Self::CdcConsumer(key) => key.fields(),
1198			Self::View(key) => key.fields(),
1199			Self::NamespaceView(key) => key.fields(),
1200			Self::PrimaryKey(key) => key.fields(),
1201			Self::OperatorState(key) => key.fields(),
1202			Self::RingBuffer(key) => key.fields(),
1203			Self::NamespaceRingBuffer(key) => key.fields(),
1204			Self::RingBufferMetadata(key) => key.fields(),
1205			Self::Flow(key) => key.fields(),
1206			Self::NamespaceFlow(key) => key.fields(),
1207			Self::Operator(key) => key.fields(),
1208			Self::OperatorByFlow(key) => key.fields(),
1209			Self::FlowEdge(key) => key.fields(),
1210			Self::FlowEdgeByFlow(key) => key.fields(),
1211			Self::OutputFrontier(key) => key.fields(),
1212			Self::Dictionary(key) => key.fields(),
1213			Self::DictionaryEntry(key) => key.fields(),
1214			Self::DictionaryEntryIndex(key) => key.fields(),
1215			Self::NamespaceDictionary(key) => key.fields(),
1216			Self::Metric(key) => key.fields(),
1217			Self::FlowVersion(key) => key.fields(),
1218			Self::RowShape(key) => key.fields(),
1219			Self::RowShapeField(key) => key.fields(),
1220			Self::SumType(key) => key.fields(),
1221			Self::NamespaceSumType(key) => key.fields(),
1222			Self::Handler(key) => key.fields(),
1223			Self::NamespaceHandler(key) => key.fields(),
1224			Self::VariantHandler(key) => key.fields(),
1225			Self::Series(key) => key.fields(),
1226			Self::NamespaceSeries(key) => key.fields(),
1227			Self::SeriesMetadata(key) => key.fields(),
1228			Self::Identity(key) => key.fields(),
1229			Self::Role(key) => key.fields(),
1230			Self::GrantedRole(key) => key.fields(),
1231			Self::Policy(key) => key.fields(),
1232			Self::PolicyOp(key) => key.fields(),
1233			Self::Migration(key) => key.fields(),
1234			Self::MigrationEvent(key) => key.fields(),
1235			Self::Authentication(key) => key.fields(),
1236			Self::ConfigStorage(key) => key.fields(),
1237			Self::Token(key) => key.fields(),
1238			Self::Source(key) => key.fields(),
1239			Self::NamespaceSource(key) => key.fields(),
1240			Self::Sink(key) => key.fields(),
1241			Self::NamespaceSink(key) => key.fields(),
1242			Self::RowSettings(key) => key.fields(),
1243			Self::Procedure(key) => key.fields(),
1244			Self::NamespaceProcedure(key) => key.fields(),
1245			Self::ProcedureParam(key) => key.fields(),
1246			Self::Binding(key) => key.fields(),
1247			Self::NamespaceBinding(key) => key.fields(),
1248			Self::OperatorSettings(key) => key.fields(),
1249			Self::ColumnSnapshot(key) => key.fields(),
1250			Self::SeriesColumnSnapshot(key) => key.fields(),
1251			Self::TableColumnSnapshot(key) => key.fields(),
1252			Self::VersionEpoch(key) => key.fields(),
1253			Self::IdentityAttribute(key) => key.fields(),
1254			Self::IdentityAttributeValue(key) => key.fields(),
1255			Self::PartitionedRow(key) => key.fields(),
1256			Self::Partition(key) => key.fields(),
1257			Self::Queue(key) => key.fields(),
1258			Self::NamespaceQueue(key) => key.fields(),
1259			Self::QueueDeduplication(key) => key.fields(),
1260			Self::Relationship(key) => key.fields(),
1261			Self::SeriesRow(key) => key.fields(),
1262			Self::PartitionedSeriesRow(key) => key.fields(),
1263			Self::QueuePartition(key) => key.fields(),
1264			Self::QueueItemState(key) => key.fields(),
1265			Self::QueueDue(key) => key.fields(),
1266			Self::QueueAttempt(key) => key.fields(),
1267			Self::QueueKeyActive(key) => key.fields(),
1268			Self::SortedViewRow(key) => key.fields(),
1269			Self::PartitionedSortedViewRow(key) => key.fields(),
1270		}
1271	}
1272}
1273
1274impl Ord for TaggedKey {
1275	fn cmp(&self, other: &Self) -> Ordering {
1276		desc(&(self.kind() as u8), &(other.kind() as u8)).then_with(|| self.fields().cmp(&other.fields()))
1277	}
1278}
1279
1280impl PartialOrd for TaggedKey {
1281	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1282		Some(self.cmp(other))
1283	}
1284}
1285
1286#[cfg(test)]
1287mod tests {
1288	use std::{borrow::Cow, cmp::Ordering};
1289
1290	use reifydb_codec::{key::encoded::EncodedKey, row::shape::fingerprint::RowShapeFingerprint};
1291	use reifydb_runtime::version_epoch::EpochSeconds;
1292	use reifydb_value::value::{
1293		Value, datetime::DateTime, dictionary::DictionaryId, identity::IdentityId, partition::Partition,
1294		row_number::RowNumber, sumtype::SumTypeId,
1295	};
1296	use smallvec::SmallVec;
1297
1298	use super::{Field, KeyFields, MetricCdcKey, MetricKey, MetricStorageKey, RawEncoding, TaggedKey};
1299	use crate::{
1300		interface::{
1301			catalog::{
1302				config::ConfigKey,
1303				flow::{FlowEdgeId, FlowId, OperatorId},
1304				id::{
1305					BindingId, ColumnId, ColumnPropertyId, ColumnSnapshotId, HandlerId, IndexId,
1306					MigrationEventId, MigrationId, NamespaceId, PrimaryKeyId, ProcedureId, QueueId,
1307					RelationshipId, RingBufferId, SequenceId, SeriesId, SinkId, SourceId, TableId,
1308					ViewId,
1309				},
1310				metrics::MetricsId,
1311				object::ObjectId,
1312				storage::StorageId,
1313			},
1314			cdc::CdcConsumerId,
1315			store::Tier,
1316		},
1317		key::{
1318			bound::{OwnedField, TaggedKeyBound},
1319			catalog::{
1320				BindingKey, ColumnPropertyKey, DictionaryEntryIndexKey, DictionaryEntryKey,
1321				DictionaryKey, HandlerKey, IndexEntryKey, IndexKey, PrimaryKeyKey, RelationshipKey,
1322				SinkKey, SourceKey, SumTypeKey, TableKey, VariantHandlerKey, ViewKey,
1323			},
1324			cdc::CdcConsumerKey,
1325			column::{
1326				ColumnKey, ColumnSequenceKey, ColumnSnapshotKey, ColumnsKey, SeriesColumnSnapshotKey,
1327				TableColumnSnapshotKey,
1328			},
1329			config::ConfigStorageKey,
1330			flow::{FlowEdgeByFlowKey, FlowEdgeKey, FlowKey, FlowVersionKey},
1331			identity::{
1332				AuthenticationKey, GrantedRoleKey, IdentityAttributeKey, IdentityAttributeValueKey,
1333				IdentityKey, PolicyKey, PolicyOpKey, RoleKey, TokenKey,
1334			},
1335			namespace::{
1336				NamespaceBindingKey, NamespaceDictionaryKey, NamespaceFlowKey, NamespaceHandlerKey,
1337				NamespaceKey, NamespaceProcedureKey, NamespaceQueueKey, NamespaceRingBufferKey,
1338				NamespaceSeriesKey, NamespaceSinkKey, NamespaceSourceKey, NamespaceSumTypeKey,
1339				NamespaceTableKey, NamespaceViewKey,
1340			},
1341			operator::{
1342				key::{OperatorByFlowKey, OperatorKey},
1343				state::{GroupId, KeyspaceId, OperatorStateKey},
1344			},
1345			operator_settings::OperatorSettingsKey,
1346			output_frontier::OutputFrontierKey,
1347			partition::PartitionKey,
1348			procedure::{ProcedureKey, ProcedureParamKey},
1349			queue::{
1350				QueueAttemptKey, QueueDeduplicationKey, QueueDueKey, QueueItemStateKey, QueueKey,
1351				QueueKeyActiveKey, QueuePartitionKey,
1352			},
1353			ringbuffer::{RingBufferKey, RingBufferMetadataKey},
1354			row::{
1355				PartitionedRowKey, PartitionedSortedViewRowKey, RowKey, RowSequenceKey, RowSettingsKey,
1356				RowShapeFieldKey, RowShapeKey, SortedViewRowKey,
1357			},
1358			series::{PartitionedSeriesRowKey, SeriesKey, SeriesMetadataKey, SeriesRowKey},
1359			sort_run::SortRun,
1360			system::{
1361				MigrationEventKey, MigrationKey, SystemSequenceKey, SystemVersion, SystemVersionKey,
1362				TransactionVersionKey, VersionEpochKey,
1363			},
1364			tag::KeyTag,
1365		},
1366		value::index::encoded::EncodedIndexKey,
1367	};
1368
1369	fn probe<K>(key: K) -> (TaggedKey, EncodedKey)
1370	where
1371		TaggedKey: From<K>,
1372	{
1373		let key = TaggedKey::from(key);
1374		let encoded = key.encode();
1375		(key, encoded)
1376	}
1377
1378	fn probe_encodable<K>(key: K) -> (TaggedKey, EncodedKey)
1379	where
1380		TaggedKey: From<K>,
1381	{
1382		let key = TaggedKey::from(key);
1383		let encoded = key.encode();
1384		(key, encoded)
1385	}
1386
1387	fn assert_ascending(probes: &[(TaggedKey, EncodedKey)]) {
1388		for pair in probes.windows(2) {
1389			let (left, left_bytes) = &pair[0];
1390			let (right, right_bytes) = &pair[1];
1391			assert_eq!(left.cmp(right), Ordering::Less, "{left:?} must sort before {right:?}");
1392			assert!(left_bytes < right_bytes, "{left:?} must encode before {right:?}");
1393		}
1394	}
1395
1396	fn dictionary_entry(dictionary: u64, hash: u8) -> DictionaryEntryKey {
1397		DictionaryEntryKey {
1398			dictionary: DictionaryId(dictionary),
1399			hash: [hash; 16],
1400		}
1401	}
1402
1403	fn series_row(variant_tag: Option<u8>) -> SeriesRowKey {
1404		SeriesRowKey {
1405			storage: StorageId::series(1),
1406			variant_tag,
1407			key: 0,
1408			sequence: 0,
1409		}
1410	}
1411
1412	fn consumer(name: &str) -> CdcConsumerKey {
1413		CdcConsumerKey {
1414			consumer: CdcConsumerId::new(name),
1415		}
1416	}
1417
1418	#[test]
1419	fn test_cross_kind_order_reverses_the_discriminant() {
1420		// Deriving Ord sorts by declaration index, which is the exact inverse of the encoded order
1421		// for every cross-kind pair; PendingWrites then merges backwards and raises no error.
1422		let mut probes = vec![
1423			probe(NamespaceKey {
1424				namespace: NamespaceId(1),
1425			}),
1426			probe(RowKey {
1427				storage: StorageId::table(1),
1428				row: RowNumber(1),
1429			}),
1430			probe_encodable(consumer("a")),
1431			probe(MetricCdcKey::new(MetricsId::System)),
1432			probe(MetricStorageKey::new(Tier::Buffer, MetricsId::System)),
1433			probe(SortedViewRowKey::new(StorageId::view(1), SortRun::new([0x10u8]), RowNumber(1))),
1434			probe(PartitionedSortedViewRowKey::new(
1435				StorageId::view(1),
1436				Partition(1),
1437				SortRun::new([0x10u8]),
1438				RowNumber(1),
1439			)),
1440		];
1441		probes.sort_by(|left, right| left.0.cmp(&right.0));
1442
1443		let encoded: Vec<EncodedKey> = probes.iter().map(|(_, bytes)| bytes.clone()).collect();
1444		let mut expected = encoded.clone();
1445		expected.sort();
1446		assert_eq!(encoded, expected);
1447
1448		assert_eq!(probes.first().unwrap().0.kind(), KeyTag::PartitionedSortedViewRow);
1449		assert_eq!(probes.last().unwrap().0.kind(), KeyTag::Namespace);
1450	}
1451
1452	#[test]
1453	fn test_object_id_tag_ascends_while_its_id_descends() {
1454		// One field encodes in two directions: a raw tag then an inverted id. Reading it as a single
1455		// direction interleaves table columns with view columns.
1456		assert_ascending(&[
1457			probe(ColumnKey {
1458				object: ObjectId::table(2),
1459				column: ColumnId(1),
1460			}),
1461			probe(ColumnKey {
1462				object: ObjectId::table(1),
1463				column: ColumnId(1),
1464			}),
1465			probe(ColumnKey {
1466				object: ObjectId::view(2),
1467				column: ColumnId(1),
1468			}),
1469			probe(ColumnKey {
1470				object: ObjectId::view(1),
1471				column: ColumnId(1),
1472			}),
1473		]);
1474	}
1475
1476	#[test]
1477	fn test_series_row_variant_tag_polarity() {
1478		// Option's own Ord puts None first and orders Some ascending; the encoder inverts both axes,
1479		// so delegating to it would place the untagged rows outside the scan that must find them.
1480		assert_ascending(&[probe(series_row(Some(2))), probe(series_row(Some(1))), probe(series_row(None))]);
1481	}
1482
1483	#[test]
1484	fn test_partitioned_series_row_variant_tag_polarity() {
1485		let partitioned = |variant_tag| PartitionedSeriesRowKey {
1486			storage: StorageId::series(1),
1487			partition: Partition(1),
1488			variant_tag,
1489			key: 0,
1490			sequence: 0,
1491		};
1492		assert_ascending(&[probe(partitioned(Some(2))), probe(partitioned(Some(1))), probe(partitioned(None))]);
1493	}
1494
1495	#[test]
1496	fn test_cdc_consumer_name_sorts_descending() {
1497		// CdcConsumerKey derives Ord over its String while encoding through extend_str, which
1498		// reverses; delegating to that derive returns the consumer list back to front.
1499		assert_ascending(&[
1500			probe_encodable(consumer("c")),
1501			probe_encodable(consumer("b")),
1502			probe_encodable(consumer("ab")),
1503			probe_encodable(consumer("a")),
1504		]);
1505	}
1506
1507	#[test]
1508	fn test_config_key_sorts_by_its_rendered_name_not_its_discriminant() {
1509		// ConfigKey derives Ord over declaration order but encodes through its Display string.
1510		assert_ascending(&[
1511			probe_encodable(ConfigStorageKey::new(ConfigKey::QueryRowBatchSize)),
1512			probe_encodable(ConfigStorageKey::new(ConfigKey::OracleWindowSize)),
1513		]);
1514	}
1515
1516	#[test]
1517	fn test_dictionary_entry_hash_sorts_ascending() {
1518		// The hash is the one field written raw, so inverting it with the rest loses every lookup.
1519		assert_ascending(&[
1520			probe(dictionary_entry(2, 0xFF)),
1521			probe(dictionary_entry(1, 0x00)),
1522			probe(dictionary_entry(1, 0x01)),
1523		]);
1524	}
1525
1526	#[test]
1527	fn test_metric_cdc_sorts_before_metric_storage() {
1528		// Both families share one kind byte and are told apart by a sub-key written descending, so
1529		// 0x02 (cdc) has to sort ahead of 0x01 (storage).
1530		assert_ascending(&[
1531			probe(MetricCdcKey::new(MetricsId::System)),
1532			probe(MetricCdcKey::new(MetricsId::Object(ObjectId::table(2)))),
1533			probe(MetricCdcKey::new(MetricsId::Object(ObjectId::table(1)))),
1534			probe(MetricStorageKey::new(Tier::Persistent, MetricsId::System)),
1535			probe(MetricStorageKey::new(Tier::Buffer, MetricsId::System)),
1536			probe(MetricStorageKey::new(Tier::Buffer, MetricsId::Object(ObjectId::table(1)))),
1537		]);
1538	}
1539
1540	#[test]
1541	fn test_index_and_index_entry_encode_the_index_id_differently() {
1542		// IndexKey writes a bare inverted id while IndexEntryKey writes a raw tag first, so one
1543		// comparison cannot serve both.
1544		assert_ascending(&[
1545			probe(IndexKey {
1546				object: ObjectId::table(1),
1547				index: IndexId::primary(PrimaryKeyId(2)),
1548			}),
1549			probe(IndexKey {
1550				object: ObjectId::table(1),
1551				index: IndexId::primary(PrimaryKeyId(1)),
1552			}),
1553		]);
1554		assert_ascending(&[
1555			probe_encodable(IndexEntryKey::new(
1556				ObjectId::table(1),
1557				IndexId::primary(PrimaryKeyId(1)),
1558				EncodedIndexKey::new([0x01u8]),
1559			)),
1560			probe_encodable(IndexEntryKey::new(
1561				ObjectId::table(1),
1562				IndexId::primary(PrimaryKeyId(1)),
1563				EncodedIndexKey::new([0x02u8]),
1564			)),
1565		]);
1566	}
1567
1568	#[test]
1569	fn test_operator_state_suffix_sorts_ascending_under_descending_fields() {
1570		// The suffix is written raw so operator state scans stay in range order; inverting it would
1571		// hand the operator its own state in reverse.
1572		assert_ascending(&[
1573			probe_encodable(OperatorStateKey::new(OperatorId(1), GroupId::ROOT, KeyspaceId(2), [0x01u8])),
1574			probe_encodable(OperatorStateKey::new(OperatorId(1), GroupId::ROOT, KeyspaceId(2), [0x02u8])),
1575			probe_encodable(OperatorStateKey::new(OperatorId(1), GroupId::ROOT, KeyspaceId(1), [0x00u8])),
1576		]);
1577	}
1578
1579	fn probes() -> Vec<(TaggedKey, EncodedKey)> {
1580		vec![
1581			probe(NamespaceKey {
1582				namespace: NamespaceId(1),
1583			}),
1584			probe(NamespaceKey {
1585				namespace: NamespaceId(2),
1586			}),
1587			probe(RowKey {
1588				storage: StorageId::table(1),
1589				row: RowNumber(1),
1590			}),
1591			probe(RowKey {
1592				storage: StorageId::table(1),
1593				row: RowNumber(2),
1594			}),
1595			probe(RowKey {
1596				storage: StorageId::view(1),
1597				row: RowNumber(1),
1598			}),
1599			probe(ColumnKey {
1600				object: ObjectId::table(1),
1601				column: ColumnId(1),
1602			}),
1603			probe(ColumnKey {
1604				object: ObjectId::queue(1),
1605				column: ColumnId(1),
1606			}),
1607			probe(IndexKey {
1608				object: ObjectId::table(1),
1609				index: IndexId::primary(PrimaryKeyId(1)),
1610			}),
1611			probe_encodable(IndexEntryKey::new(
1612				ObjectId::table(1),
1613				IndexId::primary(PrimaryKeyId(1)),
1614				EncodedIndexKey::new([0x01u8]),
1615			)),
1616			probe_encodable(IndexEntryKey::new(
1617				ObjectId::table(1),
1618				IndexId::primary(PrimaryKeyId(1)),
1619				EncodedIndexKey::new([0x01u8, 0x02]),
1620			)),
1621			probe_encodable(consumer("a")),
1622			probe_encodable(consumer("ab")),
1623			probe_encodable(consumer("b")),
1624			probe(dictionary_entry(1, 0x00)),
1625			probe(dictionary_entry(1, 0xFF)),
1626			probe(dictionary_entry(2, 0x00)),
1627			probe_encodable(DictionaryEntryIndexKey::new(DictionaryId(1), 1)),
1628			probe_encodable(DictionaryEntryIndexKey::new(DictionaryId(1), 1 << 20)),
1629			probe_encodable(DictionaryEntryIndexKey::new(DictionaryId(1), u128::from(u64::MAX) + 5)),
1630			probe_encodable(OperatorStateKey::new(OperatorId(1), GroupId::ROOT, KeyspaceId(1), [0x00u8])),
1631			probe_encodable(OperatorStateKey::new(OperatorId(1), GroupId::MAX, KeyspaceId(1), [0x00u8])),
1632			probe_encodable(ConfigStorageKey::new(ConfigKey::OracleWindowSize)),
1633			probe_encodable(ConfigStorageKey::new(ConfigKey::QueryRowBatchSize)),
1634			probe(series_row(Some(0))),
1635			probe(series_row(Some(7))),
1636			probe(series_row(None)),
1637			probe(QueueDueKey {
1638				queue: QueueId(1),
1639				partition: 0,
1640				due: DateTime::from_bits(1),
1641				row: RowNumber(1),
1642			}),
1643			probe(QueueDueKey {
1644				queue: QueueId(1),
1645				partition: 0,
1646				due: DateTime::from_bits(2),
1647				row: RowNumber(1),
1648			}),
1649			probe_encodable(QueueDeduplicationKey::new(QueueId(1), [0x01u8])),
1650			probe_encodable(QueueDeduplicationKey::new(QueueId(1), [0x01u8, 0x02])),
1651			probe_encodable(RingBufferMetadataKey::new(StorageId::ringbuffer(1))),
1652			probe_encodable(RingBufferMetadataKey {
1653				storage: StorageId::ringbuffer(1),
1654				partition_values: vec![Value::Uint8(1)],
1655			}),
1656			probe_encodable(RingBufferMetadataKey {
1657				storage: StorageId::ringbuffer(1),
1658				partition_values: vec![Value::Uint8(2)],
1659			}),
1660			probe(SortedViewRowKey::new(StorageId::view(1), SortRun::new([0x10u8]), RowNumber(1))),
1661			probe(SortedViewRowKey::new(StorageId::view(1), SortRun::new([0x10u8]), RowNumber(2))),
1662			probe(SortedViewRowKey::new(StorageId::view(1), SortRun::new([0x20u8]), RowNumber(1))),
1663			probe(PartitionedSortedViewRowKey::new(
1664				StorageId::view(1),
1665				Partition(1),
1666				SortRun::new([0x10u8]),
1667				RowNumber(1),
1668			)),
1669			probe(PartitionedSortedViewRowKey::new(
1670				StorageId::view(1),
1671				Partition(2),
1672				SortRun::new([0x10u8]),
1673				RowNumber(1),
1674			)),
1675			probe(MetricCdcKey::new(MetricsId::System)),
1676			probe(MetricCdcKey::new(MetricsId::Object(ObjectId::table(1)))),
1677			probe(MetricStorageKey::new(Tier::Buffer, MetricsId::System)),
1678			probe(MetricStorageKey::new(Tier::Persistent, MetricsId::System)),
1679			probe(SystemVersionKey {
1680				version: SystemVersion::Storage,
1681			}),
1682			probe(TransactionVersionKey {}),
1683			probe(TableKey {
1684				table: TableId(1),
1685			}),
1686		]
1687	}
1688
1689	#[test]
1690	fn test_ord_agrees_with_encoded_order_for_every_pair() {
1691		// The whole point of the impl: byte order is the merge order, so any disagreement is a
1692		// silently wrong read rather than an error.
1693		let probes = probes();
1694		for (left, left_bytes) in &probes {
1695			for (right, right_bytes) in &probes {
1696				assert_eq!(left.cmp(right), left_bytes.cmp(right_bytes), "{left:?} vs {right:?}");
1697			}
1698		}
1699	}
1700	fn assert_projection_matches_bytes(samples: Vec<(TaggedKey, EncodedKey)>, label: &str) {
1701		assert!(samples.len() >= 2, "{label} needs at least two samples to exercise a direction");
1702		for (left, left_bytes) in &samples {
1703			for (right, right_bytes) in &samples {
1704				let projected = (right.kind() as u8)
1705					.cmp(&(left.kind() as u8))
1706					.then_with(|| left.fields().cmp(&right.fields()));
1707				assert_eq!(
1708					projected,
1709					left_bytes.cmp(right_bytes),
1710					"{label}: kind and fields() disagree with encoded byte order\n  a = \
1711					 {left:?}\n  b = {right:?}\n  a bytes = {:?}\n  b bytes = {:?}",
1712					left_bytes.as_slice(),
1713					right_bytes.as_slice()
1714				);
1715			}
1716		}
1717	}
1718
1719	fn encode_via_fields(key: &TaggedKey) -> EncodedKey {
1720		let mut out = vec![!(key.kind() as u8)];
1721		for field in key.fields().iter() {
1722			field.encode(&mut out);
1723		}
1724		EncodedKey::new(out)
1725	}
1726
1727	#[test]
1728	fn every_projection_replays_the_exact_bytes_its_encoder_wrote() {
1729		// fields() carries the ordering; the encoding tag on each Field carries the codec
1730		// primitive it came from. Ordering tests cannot see a wrong tag, because Fixed and
1731		// Escaped sort alike and every integer width compares the same way, so only replaying
1732		// the bytes catches one.
1733		let probes = all_probes();
1734		assert!(probes.len() >= 80, "the byte replay is only worth running over every key type");
1735		for (key, encoded) in probes {
1736			assert_eq!(encode_via_fields(&key), encoded, "{key:?}");
1737		}
1738	}
1739
1740	#[test]
1741	fn every_hand_written_key_projects_to_the_order_its_encoder_produces() {
1742		// the derive emits a conformance test per key type; these seventeen write encode() by hand
1743		// and would otherwise have no sample varying each field, so a wrong direction would pass.
1744		assert_projection_matches_bytes(
1745			vec![
1746				probe(BindingKey {
1747					binding: BindingId(1),
1748				}),
1749				probe(BindingKey {
1750					binding: BindingId(2),
1751				}),
1752			],
1753			"BindingKey",
1754		);
1755		assert_projection_matches_bytes(
1756			vec![
1757				probe(ProcedureKey {
1758					procedure: ProcedureId::persistent(1),
1759				}),
1760				probe(ProcedureKey {
1761					procedure: ProcedureId::persistent(2),
1762				}),
1763			],
1764			"ProcedureKey",
1765		);
1766		assert_projection_matches_bytes(
1767			vec![
1768				probe(ProcedureParamKey {
1769					procedure: ProcedureId::persistent(1),
1770					param_index: 1,
1771				}),
1772				probe(ProcedureParamKey {
1773					procedure: ProcedureId::persistent(1),
1774					param_index: 2,
1775				}),
1776				probe(ProcedureParamKey {
1777					procedure: ProcedureId::persistent(2),
1778					param_index: 1,
1779				}),
1780			],
1781			"ProcedureParamKey",
1782		);
1783		assert_projection_matches_bytes(
1784			vec![
1785				probe(SinkKey {
1786					sink: SinkId(1),
1787				}),
1788				probe(SinkKey {
1789					sink: SinkId(2),
1790				}),
1791			],
1792			"SinkKey",
1793		);
1794		assert_projection_matches_bytes(
1795			vec![
1796				probe(SourceKey {
1797					source: SourceId(1),
1798				}),
1799				probe(SourceKey {
1800					source: SourceId(2),
1801				}),
1802			],
1803			"SourceKey",
1804		);
1805		assert_projection_matches_bytes(
1806			vec![
1807				probe(ViewKey {
1808					view: ViewId(1),
1809				}),
1810				probe(ViewKey {
1811					view: ViewId(2),
1812				}),
1813			],
1814			"ViewKey",
1815		);
1816		assert_projection_matches_bytes(
1817			vec![
1818				probe(SumTypeKey {
1819					sumtype: SumTypeId(1),
1820				}),
1821				probe(SumTypeKey {
1822					sumtype: SumTypeId(2),
1823				}),
1824			],
1825			"SumTypeKey",
1826		);
1827		assert_projection_matches_bytes(
1828			vec![
1829				probe_encodable(DictionaryEntryIndexKey {
1830					dictionary: DictionaryId(1),
1831					id: 1,
1832				}),
1833				probe_encodable(DictionaryEntryIndexKey {
1834					dictionary: DictionaryId(1),
1835					id: u128::from(u64::MAX) + 1,
1836				}),
1837				probe_encodable(DictionaryEntryIndexKey {
1838					dictionary: DictionaryId(2),
1839					id: 1,
1840				}),
1841			],
1842			"DictionaryEntryIndexKey",
1843		);
1844		assert_projection_matches_bytes(
1845			vec![
1846				probe_encodable(IndexEntryKey::new(
1847					ObjectId::table(1),
1848					IndexId::primary(PrimaryKeyId(1)),
1849					EncodedIndexKey::new([0x01u8]),
1850				)),
1851				probe_encodable(IndexEntryKey::new(
1852					ObjectId::table(1),
1853					IndexId::primary(PrimaryKeyId(1)),
1854					EncodedIndexKey::new([0x02u8]),
1855				)),
1856				probe_encodable(IndexEntryKey::new(
1857					ObjectId::table(1),
1858					IndexId::primary(PrimaryKeyId(2)),
1859					EncodedIndexKey::new([0x01u8]),
1860				)),
1861				probe_encodable(IndexEntryKey::new(
1862					ObjectId::view(1),
1863					IndexId::primary(PrimaryKeyId(1)),
1864					EncodedIndexKey::new([0x01u8]),
1865				)),
1866			],
1867			"IndexEntryKey",
1868		);
1869		assert_projection_matches_bytes(
1870			vec![
1871				probe_encodable(CdcConsumerKey::new(CdcConsumerId::new("a"))),
1872				probe_encodable(CdcConsumerKey::new(CdcConsumerId::new("b"))),
1873				probe_encodable(CdcConsumerKey::new(CdcConsumerId::new("ab"))),
1874			],
1875			"CdcConsumerKey",
1876		);
1877		assert_projection_matches_bytes(
1878			vec![
1879				probe_encodable(ConfigStorageKey::new(ConfigKey::QueryRowBatchSize)),
1880				probe_encodable(ConfigStorageKey::new(ConfigKey::OracleWindowSize)),
1881			],
1882			"ConfigStorageKey",
1883		);
1884		assert_projection_matches_bytes(
1885			vec![
1886				probe_encodable(QueueDeduplicationKey::new(QueueId(1), [0x01u8])),
1887				probe_encodable(QueueDeduplicationKey::new(QueueId(1), [0x02u8])),
1888				probe_encodable(QueueDeduplicationKey::new(QueueId(1), [0x01u8, 0x00])),
1889				probe_encodable(QueueDeduplicationKey::new(QueueId(2), [0x01u8])),
1890			],
1891			"QueueDeduplicationKey",
1892		);
1893		assert_projection_matches_bytes(
1894			vec![
1895				probe_encodable(OperatorStateKey::new(
1896					OperatorId(1),
1897					GroupId::ROOT,
1898					KeyspaceId(1),
1899					[0x01u8],
1900				)),
1901				probe_encodable(OperatorStateKey::new(
1902					OperatorId(1),
1903					GroupId::ROOT,
1904					KeyspaceId(1),
1905					[0x02u8],
1906				)),
1907				probe_encodable(OperatorStateKey::new(
1908					OperatorId(1),
1909					GroupId::ROOT,
1910					KeyspaceId(2),
1911					[0x01u8],
1912				)),
1913				probe_encodable(OperatorStateKey::new(
1914					OperatorId(1),
1915					GroupId::from_bytes([0x01u8; 24]),
1916					KeyspaceId(1),
1917					[0x01u8],
1918				)),
1919				probe_encodable(OperatorStateKey::new(
1920					OperatorId(2),
1921					GroupId::ROOT,
1922					KeyspaceId(1),
1923					[0x01u8],
1924				)),
1925			],
1926			"OperatorStateKey",
1927		);
1928		assert_projection_matches_bytes(
1929			vec![
1930				probe_encodable(RingBufferMetadataKey {
1931					storage: StorageId::ringbuffer(1),
1932					partition_values: vec![Value::Uint8(1)],
1933				}),
1934				probe_encodable(RingBufferMetadataKey {
1935					storage: StorageId::ringbuffer(1),
1936					partition_values: vec![Value::Uint8(2)],
1937				}),
1938				probe_encodable(RingBufferMetadataKey {
1939					storage: StorageId::ringbuffer(2),
1940					partition_values: vec![Value::Uint8(1)],
1941				}),
1942			],
1943			"RingBufferMetadataKey",
1944		);
1945		assert_projection_matches_bytes(
1946			vec![
1947				probe(SortedViewRowKey::new(StorageId::view(1), SortRun::new([0x10u8]), RowNumber(1))),
1948				probe(SortedViewRowKey::new(StorageId::view(1), SortRun::new([0x10u8]), RowNumber(2))),
1949				probe(SortedViewRowKey::new(StorageId::view(1), SortRun::new([0x20u8]), RowNumber(1))),
1950				probe(SortedViewRowKey::new(
1951					StorageId::view(1),
1952					SortRun::new([0x10u8, 0x00]),
1953					RowNumber(1),
1954				)),
1955				probe(SortedViewRowKey::new(StorageId::view(2), SortRun::new([0x10u8]), RowNumber(1))),
1956			],
1957			"SortedViewRowKey",
1958		);
1959		assert_projection_matches_bytes(
1960			vec![
1961				probe(PartitionedSortedViewRowKey::new(
1962					StorageId::view(1),
1963					Partition(1),
1964					SortRun::new([0x10u8]),
1965					RowNumber(1),
1966				)),
1967				probe(PartitionedSortedViewRowKey::new(
1968					StorageId::view(1),
1969					Partition(1),
1970					SortRun::new([0x10u8]),
1971					RowNumber(2),
1972				)),
1973				probe(PartitionedSortedViewRowKey::new(
1974					StorageId::view(1),
1975					Partition(1),
1976					SortRun::new([0x20u8]),
1977					RowNumber(1),
1978				)),
1979				probe(PartitionedSortedViewRowKey::new(
1980					StorageId::view(1),
1981					Partition(2),
1982					SortRun::new([0x10u8]),
1983					RowNumber(1),
1984				)),
1985				probe(PartitionedSortedViewRowKey::new(
1986					StorageId::view(2),
1987					Partition(1),
1988					SortRun::new([0x10u8]),
1989					RowNumber(1),
1990				)),
1991			],
1992			"PartitionedSortedViewRowKey",
1993		);
1994		assert_projection_matches_bytes(
1995			vec![
1996				probe(MetricStorageKey::new(Tier::Buffer, MetricsId::System)),
1997				probe(MetricStorageKey::new(Tier::Persistent, MetricsId::System)),
1998				probe(MetricStorageKey::new(Tier::Buffer, MetricsId::Object(ObjectId::table(1)))),
1999				probe(MetricStorageKey::new(Tier::Buffer, MetricsId::Object(ObjectId::table(2)))),
2000				probe(MetricStorageKey::new(Tier::Buffer, MetricsId::Object(ObjectId::view(1)))),
2001				probe(MetricCdcKey::new(MetricsId::System)),
2002				probe(MetricCdcKey::new(MetricsId::Object(ObjectId::table(1)))),
2003				probe(MetricCdcKey::new(MetricsId::Object(ObjectId::table(2)))),
2004			],
2005			"MetricKey",
2006		);
2007	}
2008
2009	fn all_probes() -> Vec<(TaggedKey, EncodedKey)> {
2010		vec![
2011			probe(NamespaceKey {
2012				namespace: NamespaceId(1),
2013			}),
2014			probe(TableKey {
2015				table: TableId(2),
2016			}),
2017			probe(RowKey {
2018				storage: StorageId::table(3),
2019				row: RowNumber(4),
2020			}),
2021			probe(NamespaceTableKey {
2022				namespace: NamespaceId(5),
2023				table: TableId(6),
2024			}),
2025			probe(SystemSequenceKey {
2026				sequence: SequenceId(7),
2027			}),
2028			probe(ColumnsKey {
2029				column: ColumnId(8),
2030			}),
2031			probe(ColumnKey {
2032				object: ObjectId::view(9),
2033				column: ColumnId(10),
2034			}),
2035			probe(RowSequenceKey {
2036				storage: StorageId::view(11),
2037			}),
2038			probe(ColumnPropertyKey {
2039				column: ColumnId(12),
2040				property: ColumnPropertyId(13),
2041			}),
2042			probe(SystemVersionKey {
2043				version: SystemVersion::Storage,
2044			}),
2045			probe(TransactionVersionKey {}),
2046			probe(IndexKey {
2047				object: ObjectId::table(14),
2048				index: IndexId::primary(PrimaryKeyId(15)),
2049			}),
2050			probe_encodable(IndexEntryKey::new(
2051				ObjectId::table(16),
2052				IndexId::primary(PrimaryKeyId(17)),
2053				EncodedIndexKey::new([0x01u8, 0x02]),
2054			)),
2055			probe(ColumnSequenceKey {
2056				object: ObjectId::table(18),
2057				column: ColumnId(19),
2058			}),
2059			probe_encodable(CdcConsumerKey {
2060				consumer: CdcConsumerId::new("consumer"),
2061			}),
2062			probe(ViewKey {
2063				view: ViewId(20),
2064			}),
2065			probe(NamespaceViewKey {
2066				namespace: NamespaceId(21),
2067				view: ViewId(22),
2068			}),
2069			probe(PrimaryKeyKey {
2070				primary_key: PrimaryKeyId(23),
2071			}),
2072			probe_encodable(OperatorStateKey::new(
2073				OperatorId(24),
2074				GroupId::ROOT,
2075				KeyspaceId(2),
2076				[0x01u8, 0x02],
2077			)),
2078			probe(RingBufferKey {
2079				ringbuffer: RingBufferId(25),
2080			}),
2081			probe(NamespaceRingBufferKey {
2082				namespace: NamespaceId(26),
2083				ringbuffer: RingBufferId(27),
2084			}),
2085			probe_encodable(RingBufferMetadataKey {
2086				storage: StorageId::ringbuffer(28),
2087				partition_values: vec![Value::Utf8("east".to_string()), Value::Uint8(3)],
2088			}),
2089			probe(FlowKey {
2090				flow: FlowId(29),
2091			}),
2092			probe(NamespaceFlowKey {
2093				namespace: NamespaceId(30),
2094				flow: FlowId(31),
2095			}),
2096			probe(OperatorKey {
2097				operator: OperatorId(32),
2098			}),
2099			probe(OperatorByFlowKey {
2100				flow: FlowId(33),
2101				operator: OperatorId(34),
2102			}),
2103			probe(FlowEdgeKey {
2104				edge: FlowEdgeId(35),
2105			}),
2106			probe(FlowEdgeByFlowKey {
2107				flow: FlowId(36),
2108				edge: FlowEdgeId(37),
2109			}),
2110			probe(OutputFrontierKey {
2111				object: ObjectId::view(38),
2112			}),
2113			probe(DictionaryKey {
2114				dictionary: DictionaryId(39),
2115			}),
2116			probe(DictionaryEntryKey {
2117				dictionary: DictionaryId(40),
2118				hash: [0x5Au8; 16],
2119			}),
2120			probe_encodable(DictionaryEntryIndexKey::new(DictionaryId(41), u128::from(u64::MAX) + 9)),
2121			probe(NamespaceDictionaryKey {
2122				namespace: NamespaceId(42),
2123				dictionary: DictionaryId(43),
2124			}),
2125			probe(MetricStorageKey::new(Tier::Persistent, MetricsId::Object(ObjectId::table(44)))),
2126			probe(MetricCdcKey::new(MetricsId::System)),
2127			probe(FlowVersionKey {
2128				flow: FlowId(45),
2129			}),
2130			probe(RowShapeKey {
2131				fingerprint: RowShapeFingerprint::new(46),
2132			}),
2133			probe(RowShapeFieldKey {
2134				shape_fingerprint: RowShapeFingerprint::new(47),
2135				field_index: 48,
2136			}),
2137			probe(SumTypeKey {
2138				sumtype: SumTypeId(49),
2139			}),
2140			probe(NamespaceSumTypeKey {
2141				namespace: NamespaceId(50),
2142				sumtype: SumTypeId(51),
2143			}),
2144			probe(HandlerKey {
2145				handler: HandlerId(52),
2146			}),
2147			probe(NamespaceHandlerKey {
2148				namespace: NamespaceId(53),
2149				handler: HandlerId(54),
2150			}),
2151			probe(VariantHandlerKey {
2152				namespace: NamespaceId(55),
2153				sumtype: SumTypeId(56),
2154				variant_tag: 57,
2155				handler: HandlerId(58),
2156			}),
2157			probe(SeriesKey {
2158				series: SeriesId(59),
2159			}),
2160			probe(NamespaceSeriesKey {
2161				namespace: NamespaceId(60),
2162				series: SeriesId(61),
2163			}),
2164			probe(SeriesMetadataKey {
2165				storage: StorageId::series(62),
2166			}),
2167			probe(IdentityKey {
2168				identity: IdentityId::anonymous(),
2169			}),
2170			probe(RoleKey {
2171				role: 63,
2172			}),
2173			probe(GrantedRoleKey {
2174				identity: IdentityId::root(),
2175				role: 64,
2176			}),
2177			probe(PolicyKey {
2178				policy: 65,
2179			}),
2180			probe(PolicyOpKey {
2181				policy: 66,
2182				op_index: 67,
2183			}),
2184			probe(MigrationKey {
2185				migration: MigrationId(68),
2186			}),
2187			probe(MigrationEventKey {
2188				event: MigrationEventId(69),
2189			}),
2190			probe(AuthenticationKey {
2191				authentication: 70,
2192			}),
2193			probe_encodable(ConfigStorageKey::new(ConfigKey::QueryRowBatchSize)),
2194			probe(TokenKey {
2195				token: 71,
2196			}),
2197			probe(SourceKey {
2198				source: SourceId(72),
2199			}),
2200			probe(NamespaceSourceKey {
2201				namespace: NamespaceId(73),
2202				source: SourceId(74),
2203			}),
2204			probe(SinkKey {
2205				sink: SinkId(75),
2206			}),
2207			probe(NamespaceSinkKey {
2208				namespace: NamespaceId(76),
2209				sink: SinkId(77),
2210			}),
2211			probe(RowSettingsKey {
2212				storage: StorageId::ringbuffer(78),
2213			}),
2214			probe(ProcedureKey {
2215				procedure: ProcedureId::persistent(79),
2216			}),
2217			probe(NamespaceProcedureKey {
2218				namespace: NamespaceId(80),
2219				procedure: ProcedureId::persistent(81),
2220			}),
2221			probe(ProcedureParamKey {
2222				procedure: ProcedureId::persistent(82),
2223				param_index: 83,
2224			}),
2225			probe(BindingKey {
2226				binding: BindingId(84),
2227			}),
2228			probe(NamespaceBindingKey {
2229				namespace: NamespaceId(85),
2230				binding: BindingId(86),
2231			}),
2232			probe(OperatorSettingsKey {
2233				operator: OperatorId(87),
2234			}),
2235			probe(ColumnSnapshotKey {
2236				snapshot: ColumnSnapshotId(88),
2237			}),
2238			probe(SeriesColumnSnapshotKey {
2239				series: SeriesId(89),
2240				snapshot: ColumnSnapshotId(90),
2241			}),
2242			probe(TableColumnSnapshotKey {
2243				table: TableId(91),
2244				snapshot: ColumnSnapshotId(92),
2245			}),
2246			probe(VersionEpochKey {
2247				bucket: EpochSeconds::new(93),
2248			}),
2249			probe(IdentityAttributeKey {
2250				attribute: 94,
2251			}),
2252			probe(IdentityAttributeValueKey {
2253				identity: IdentityId::anonymous(),
2254				attribute: 95,
2255			}),
2256			probe(PartitionedRowKey {
2257				storage: StorageId::table(96),
2258				partition: Partition(97),
2259				row: RowNumber(98),
2260			}),
2261			probe(PartitionKey {
2262				object: ObjectId::table(99),
2263				partition: Partition(100),
2264			}),
2265			probe(QueueKey {
2266				queue: QueueId(101),
2267			}),
2268			probe(NamespaceQueueKey {
2269				namespace: NamespaceId(102),
2270				queue: QueueId(103),
2271			}),
2272			probe_encodable(QueueDeduplicationKey::new(QueueId(104), [0xFFu8, 0x00, 0xFF])),
2273			probe(RelationshipKey {
2274				relationship: RelationshipId(105),
2275			}),
2276			probe(SeriesRowKey {
2277				storage: StorageId::series(106),
2278				variant_tag: Some(5),
2279				key: 107,
2280				sequence: 108,
2281			}),
2282			probe(PartitionedSeriesRowKey {
2283				storage: StorageId::series(109),
2284				partition: Partition(110),
2285				variant_tag: None,
2286				key: 111,
2287				sequence: 112,
2288			}),
2289			probe(QueuePartitionKey {
2290				queue: QueueId(113),
2291				partition: 114,
2292			}),
2293			probe(QueueItemStateKey {
2294				queue: QueueId(115),
2295				partition: 116,
2296				row: RowNumber(117),
2297			}),
2298			probe(QueueDueKey {
2299				queue: QueueId(118),
2300				partition: 119,
2301				due: DateTime::from_bits(120),
2302				row: RowNumber(121),
2303			}),
2304			probe(QueueAttemptKey {
2305				queue: QueueId(122),
2306				row: RowNumber(123),
2307				attempt: 124,
2308			}),
2309			probe(QueueKeyActiveKey {
2310				queue: QueueId(125),
2311				partition: 126,
2312				key_hash: 127,
2313				row: RowNumber(128),
2314			}),
2315			probe(SortedViewRowKey::new(
2316				StorageId::view(129),
2317				SortRun::new([0x00u8, 0xFF, 0x10]),
2318				RowNumber(130),
2319			)),
2320			probe(PartitionedSortedViewRowKey::new(
2321				StorageId::view(131),
2322				Partition(132),
2323				SortRun::new([0x10u8]),
2324				RowNumber(133),
2325			)),
2326		]
2327	}
2328
2329	fn owned_field(field: &Field<'_>) -> OwnedField {
2330		match field {
2331			Field::UAsc(width, value) => Field::UAsc(*width, *value),
2332			Field::UDesc(width, value) => Field::UDesc(*width, *value),
2333			Field::BytesDesc(encoding, bytes) => {
2334				Field::BytesDesc(*encoding, Cow::Owned(bytes.as_ref().to_vec()))
2335			}
2336			Field::RawAsc(encoding, bytes) => Field::RawAsc(*encoding, Cow::Owned(bytes.as_ref().to_vec())),
2337		}
2338	}
2339
2340	/// Every bound shape a producer can build for `key`: the bare kind and its successor, and each
2341	/// head of the key's own field list as both a `Prefix` and a `PrefixEnd`.
2342	///
2343	/// The last shape drops a byte from a trailing verbatim field, which is what
2344	/// `IndexEntryKey::key_prefix_range` does: a head whose final field is a truncation rather
2345	/// than a whole value. Terminated and fixed-width encodings are not truncated here because no
2346	/// producer truncates them, and a partial value under those encodings is not a byte prefix of
2347	/// the whole one.
2348	fn bounds_derived_from(key: &TaggedKey) -> Vec<TaggedKeyBound> {
2349		let mut out = vec![TaggedKeyBound::Kind(key.kind()), TaggedKeyBound::KindEnd(key.kind())];
2350		let fields = key.fields();
2351
2352		for len in 0..=fields.len() {
2353			let head: SmallVec<[OwnedField; 6]> = fields[..len].iter().map(owned_field).collect();
2354			out.push(TaggedKeyBound::Prefix(key.kind(), head.clone()));
2355			if len > 0 {
2356				// `PrefixEnd` with no fields is not a shape a producer can reach: every
2357				// `TaggedKeyBoundRange::prefix` call passes fields, and the end of a whole
2358				// kind span is spelled `KindEnd`, which is generated above. The two
2359				// encode alike but order differently, since only `KindEnd` carries the
2360				// decrement in its kind byte rather than in the encoded increment.
2361				out.push(TaggedKeyBound::PrefixEnd(key.kind(), head));
2362			}
2363		}
2364
2365		if let Some(Field::RawAsc(RawEncoding::Verbatim, bytes)) = fields.last() {
2366			if bytes.len() > 1 {
2367				let mut head: SmallVec<[OwnedField; 6]> =
2368					fields[..fields.len() - 1].iter().map(owned_field).collect();
2369				head.push(Field::RawAsc(
2370					RawEncoding::Verbatim,
2371					Cow::Owned(bytes[..bytes.len() - 1].to_vec()),
2372				));
2373				out.push(TaggedKeyBound::Prefix(key.kind(), head.clone()));
2374				out.push(TaggedKeyBound::PrefixEnd(key.kind(), head));
2375			}
2376		}
2377
2378		out
2379	}
2380
2381	#[test]
2382	fn every_bound_shape_orders_against_every_key_the_way_their_bytes_do() {
2383		// A bound exists only to delimit a scan, and the scan is merged on bytes. Where a bound
2384		// and a key disagree, a range silently admits or drops that row: the typed side of the
2385		// scan says one thing and the storage engine another, with no error either way.
2386		//
2387		// The shapes here are derived from the keys themselves rather than listed per producer,
2388		// so a new key type is covered the moment it joins the probe set, and every field
2389		// position is exercised rather than only the ones a producer happens to slice at today.
2390		let probes = all_probes();
2391		let bounds: Vec<TaggedKeyBound> = probes.iter().flat_map(|(key, _)| bounds_derived_from(key)).collect();
2392
2393		for bound in &bounds {
2394			let bound_bytes = bound.encode();
2395			if bound_bytes.as_slice().is_empty() {
2396				// `PrefixEnd` collapses to nothing when every byte it would increment is
2397				// already 0xff. That is the encoding of an unbounded edge, which no
2398				// producer emits and `TaggedKeyBoundRange::empty` relies on.
2399				continue;
2400			}
2401			for (key, key_bytes) in &probes {
2402				let probe = TaggedKeyBound::Key(key.clone());
2403				assert_eq!(
2404					bound.cmp(&probe),
2405					bound_bytes.as_slice().cmp(key_bytes.as_slice()),
2406					"bound order disagrees with encoded order\n  bound = {bound:?}\n  key \
2407					 = {key:?}\n  bound bytes = {:02x?}\n  key bytes = {:02x?}",
2408					bound_bytes.as_slice(),
2409					key_bytes.as_slice()
2410				);
2411			}
2412		}
2413	}
2414
2415	#[test]
2416	fn kind_end_is_the_spelling_that_agrees_with_bytes_for_a_whole_kind_span() {
2417		// `KindEnd(k)` and `PrefixEnd(k, [])` encode to the same byte, the start of the next kind
2418		// down, but only `KindEnd` also orders there. Producers must use `KindEnd`, which
2419		// `TaggedKeyBoundRange::kind` does; this pins that the correct spelling stays correct.
2420		for (key, key_bytes) in all_probes() {
2421			let end = TaggedKeyBound::KindEnd(key.kind());
2422			let end_bytes = end.encode();
2423			let probe = TaggedKeyBound::Key(key.clone());
2424
2425			assert_eq!(
2426				end.cmp(&probe),
2427				end_bytes.as_slice().cmp(key_bytes.as_slice()),
2428				"KindEnd disagrees with its bytes for {key:?}"
2429			);
2430			assert_eq!(
2431				end_bytes.as_slice(),
2432				TaggedKeyBound::PrefixEnd(key.kind(), SmallVec::new()).encode().as_slice(),
2433				"KindEnd and an empty PrefixEnd must still encode alike for {key:?}"
2434			);
2435		}
2436	}
2437
2438	#[test]
2439	fn test_every_variant_round_trips_through_the_shared_decoder() {
2440		// A key that comes back as the wrong variant rewrites the wrong row once Delta carries it.
2441		for (key, bytes) in all_probes() {
2442			assert_eq!(TaggedKey::decode(&bytes), Some(key.clone()), "{key:?}");
2443		}
2444	}
2445
2446	#[test]
2447	fn test_encoding_through_any_key_is_byte_identical() {
2448		// Any drift writes a second on-disk key for a row that already exists under the old bytes.
2449		for (key, bytes) in all_probes() {
2450			assert_eq!(key.encode(), bytes, "{key:?}");
2451		}
2452	}
2453
2454	#[test]
2455	fn test_probes_cover_every_live_kind() {
2456		// Without this a variant can be added to the enum and left out of encode and decode.
2457		let mut kinds: Vec<u8> = all_probes().iter().map(|(key, _)| key.kind() as u8).collect();
2458		kinds.sort_unstable();
2459		kinds.dedup();
2460		assert_eq!(kinds.len(), 87);
2461	}
2462
2463	#[test]
2464	fn test_metric_sub_families_decode_into_their_own_variant() {
2465		// Both families share kind 0x22; the wrong pick loses the tier and reads another counter.
2466		let storage = MetricStorageKey::new(Tier::Persistent, MetricsId::System);
2467		let cdc = MetricCdcKey::new(MetricsId::System);
2468		assert_eq!(TaggedKey::decode(&storage.encode()), Some(TaggedKey::Metric(MetricKey::Storage(storage))));
2469		assert_eq!(TaggedKey::decode(&cdc.encode()), Some(TaggedKey::Metric(MetricKey::Cdc(cdc))));
2470	}
2471
2472	#[test]
2473	fn test_decode_rejects_bytes_that_name_no_live_kind() {
2474		// 0x24-0x26 and 0x3F were removed; a hole must not resurrect as a neighbouring key.
2475		assert_eq!(TaggedKey::decode(&EncodedKey::new(Vec::<u8>::new())), None);
2476		for hole in [0x24u8, 0x25, 0x26, 0x3F] {
2477			assert_eq!(TaggedKey::decode(&EncodedKey::new(vec![!hole, 0x00, 0x01])), None);
2478		}
2479	}
2480
2481	#[test]
2482	fn test_decode_rejects_a_truncated_payload() {
2483		// A short read must fail rather than hand back a key built from whatever bytes arrived.
2484		let bytes = RowKey {
2485			storage: StorageId::table(1),
2486			row: RowNumber(1),
2487		}
2488		.encode();
2489		let mut truncated = bytes.as_slice().to_vec();
2490		truncated.truncate(truncated.len() - 1);
2491		assert_eq!(TaggedKey::decode(&EncodedKey::new(truncated)), None);
2492	}
2493
2494	#[test]
2495	fn test_index_entry_with_an_empty_suffix_round_trips() {
2496		// set_encoded decodes what it is handed, so a write-only key would error on write.
2497		let key = IndexEntryKey::new(
2498			ObjectId::table(1),
2499			IndexId::primary(PrimaryKeyId(1)),
2500			EncodedIndexKey::new([0u8; 0]),
2501		);
2502		let bytes = key.encode();
2503		assert_eq!(TaggedKey::from(key.clone()).encode(), bytes);
2504		assert_eq!(TaggedKey::decode(&bytes), Some(TaggedKey::from(key)));
2505	}
2506
2507	#[test]
2508	fn test_any_key_fits_two_machine_words_beyond_an_encoded_key() {
2509		// Delta holds one key per pending write, so this number sets the per-transaction budget.
2510		assert_eq!(size_of::<EncodedKey>(), 48);
2511		assert_eq!(size_of::<TaggedKey>(), 96);
2512		assert_eq!(size_of::<PartitionedSortedViewRowKey>(), size_of::<TaggedKey>());
2513	}
2514}