Skip to main content

reifydb_core/interface/
resolved.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use std::sync::Arc;
5
6use reifydb_value::{
7	error::NumberOutOfRangeDescriptor,
8	fragment::Fragment,
9	value::{constraint::TypeConstraint, value_type::ValueType},
10};
11use serde::{Deserialize, Serialize};
12
13use super::catalog::{
14	column::Column, dictionary::Dictionary, namespace::Namespace, property::ColumnPropertyKind, queue::Queue,
15	ringbuffer::RingBuffer, series::Series, table::Table, view::View, vtable::VTable,
16};
17
18#[derive(Debug, Clone)]
19pub enum ResolvedNamespace {
20	Local(Arc<ResolvedNamespaceInner>),
21	Remote(Arc<ResolvedNamespaceInner>),
22}
23
24#[derive(Debug)]
25pub struct ResolvedNamespaceInner {
26	identifier: Fragment,
27	def: Namespace,
28}
29
30impl ResolvedNamespace {
31	pub fn new(identifier: Fragment, def: Namespace) -> Self {
32		let is_remote = def.is_remote();
33		let inner = Arc::new(ResolvedNamespaceInner {
34			identifier,
35			def,
36		});
37		if is_remote {
38			Self::Remote(inner)
39		} else {
40			Self::Local(inner)
41		}
42	}
43
44	fn inner(&self) -> &ResolvedNamespaceInner {
45		match self {
46			Self::Local(inner) | Self::Remote(inner) => inner,
47		}
48	}
49
50	pub fn name(&self) -> &str {
51		self.inner().def.name()
52	}
53
54	pub fn def(&self) -> &Namespace {
55		&self.inner().def
56	}
57
58	pub fn fragment(&self) -> &Fragment {
59		&self.inner().identifier
60	}
61
62	pub fn is_remote(&self) -> bool {
63		matches!(self, Self::Remote(_))
64	}
65
66	pub fn address(&self) -> Option<&str> {
67		self.inner().def.address()
68	}
69
70	pub fn to_static(&self) -> ResolvedNamespace {
71		let inner = self.inner();
72		ResolvedNamespace::new(Fragment::internal(inner.identifier.text()), inner.def.clone())
73	}
74}
75
76#[derive(Debug, Clone)]
77pub struct ResolvedTable(Arc<ResolvedTableInner>);
78
79#[derive(Debug)]
80struct ResolvedTableInner {
81	pub identifier: Fragment,
82	pub namespace: ResolvedNamespace,
83	pub def: Table,
84}
85
86impl ResolvedTable {
87	pub fn new(identifier: Fragment, namespace: ResolvedNamespace, def: Table) -> Self {
88		Self(Arc::new(ResolvedTableInner {
89			identifier,
90			namespace,
91			def,
92		}))
93	}
94
95	pub fn name(&self) -> &str {
96		&self.0.def.name
97	}
98
99	pub fn def(&self) -> &Table {
100		&self.0.def
101	}
102
103	pub fn namespace(&self) -> &ResolvedNamespace {
104		&self.0.namespace
105	}
106
107	pub fn identifier(&self) -> &Fragment {
108		&self.0.identifier
109	}
110
111	pub fn fully_qualified_name(&self) -> String {
112		format!("{}::{}", self.0.namespace.name(), self.name())
113	}
114
115	pub fn columns(&self) -> &[Column] {
116		&self.0.def.columns
117	}
118
119	pub fn find_column(&self, name: &str) -> Option<&Column> {
120		self.0.def.columns.iter().find(|c| c.name == name)
121	}
122
123	pub fn to_static(&self) -> ResolvedTable {
124		ResolvedTable(Arc::new(ResolvedTableInner {
125			identifier: Fragment::internal(self.0.identifier.text()),
126			namespace: self.0.namespace.clone(),
127			def: self.0.def.clone(),
128		}))
129	}
130}
131
132#[derive(Debug, Clone)]
133pub struct ResolvedTableVirtual(Arc<ResolvedTableVirtualInner>);
134
135#[derive(Debug)]
136struct ResolvedTableVirtualInner {
137	pub identifier: Fragment,
138	pub namespace: ResolvedNamespace,
139	pub def: VTable,
140}
141
142impl ResolvedTableVirtual {
143	pub fn new(identifier: Fragment, namespace: ResolvedNamespace, def: VTable) -> Self {
144		Self(Arc::new(ResolvedTableVirtualInner {
145			identifier,
146			namespace,
147			def,
148		}))
149	}
150
151	pub fn name(&self) -> &str {
152		&self.0.def.name
153	}
154
155	pub fn def(&self) -> &VTable {
156		&self.0.def
157	}
158
159	pub fn namespace(&self) -> &ResolvedNamespace {
160		&self.0.namespace
161	}
162
163	pub fn identifier(&self) -> &Fragment {
164		&self.0.identifier
165	}
166
167	pub fn columns(&self) -> &[Column] {
168		&self.0.def.columns
169	}
170
171	pub fn to_static(&self) -> ResolvedTableVirtual {
172		ResolvedTableVirtual(Arc::new(ResolvedTableVirtualInner {
173			identifier: Fragment::internal(self.0.identifier.text()),
174			namespace: self.0.namespace.clone(),
175			def: self.0.def.clone(),
176		}))
177	}
178}
179
180#[derive(Debug, Clone)]
181pub struct ResolvedRingBuffer(Arc<ResolvedRingBufferInner>);
182
183#[derive(Debug)]
184struct ResolvedRingBufferInner {
185	pub identifier: Fragment,
186	pub namespace: ResolvedNamespace,
187	pub def: RingBuffer,
188}
189
190impl ResolvedRingBuffer {
191	pub fn new(identifier: Fragment, namespace: ResolvedNamespace, def: RingBuffer) -> Self {
192		Self(Arc::new(ResolvedRingBufferInner {
193			identifier,
194			namespace,
195			def,
196		}))
197	}
198
199	pub fn name(&self) -> &str {
200		&self.0.def.name
201	}
202
203	pub fn def(&self) -> &RingBuffer {
204		&self.0.def
205	}
206
207	pub fn namespace(&self) -> &ResolvedNamespace {
208		&self.0.namespace
209	}
210
211	pub fn identifier(&self) -> &Fragment {
212		&self.0.identifier
213	}
214
215	pub fn fully_qualified_name(&self) -> String {
216		format!("{}::{}", self.0.namespace.name(), self.name())
217	}
218
219	pub fn columns(&self) -> &[Column] {
220		&self.0.def.columns
221	}
222
223	pub fn find_column(&self, name: &str) -> Option<&Column> {
224		self.0.def.columns.iter().find(|c| c.name == name)
225	}
226
227	pub fn to_static(&self) -> ResolvedRingBuffer {
228		ResolvedRingBuffer(Arc::new(ResolvedRingBufferInner {
229			identifier: Fragment::internal(self.0.identifier.text()),
230			namespace: self.0.namespace.clone(),
231			def: self.0.def.clone(),
232		}))
233	}
234}
235
236#[derive(Debug, Clone)]
237pub struct ResolvedDictionary(Arc<ResolvedDictionaryInner>);
238
239#[derive(Debug)]
240struct ResolvedDictionaryInner {
241	pub identifier: Fragment,
242	pub namespace: ResolvedNamespace,
243	pub def: Dictionary,
244}
245
246impl ResolvedDictionary {
247	pub fn new(identifier: Fragment, namespace: ResolvedNamespace, def: Dictionary) -> Self {
248		Self(Arc::new(ResolvedDictionaryInner {
249			identifier,
250			namespace,
251			def,
252		}))
253	}
254
255	pub fn name(&self) -> &str {
256		&self.0.def.name
257	}
258
259	pub fn def(&self) -> &Dictionary {
260		&self.0.def
261	}
262
263	pub fn namespace(&self) -> &ResolvedNamespace {
264		&self.0.namespace
265	}
266
267	pub fn identifier(&self) -> &Fragment {
268		&self.0.identifier
269	}
270
271	pub fn fully_qualified_name(&self) -> String {
272		format!("{}::{}", self.0.namespace.name(), self.name())
273	}
274
275	pub fn to_static(&self) -> ResolvedDictionary {
276		ResolvedDictionary(Arc::new(ResolvedDictionaryInner {
277			identifier: Fragment::internal(self.0.identifier.text()),
278			namespace: self.0.namespace.clone(),
279			def: self.0.def.clone(),
280		}))
281	}
282}
283
284#[derive(Debug, Clone)]
285pub struct ResolvedSeries(Arc<ResolvedSeriesInner>);
286
287#[derive(Debug)]
288struct ResolvedSeriesInner {
289	pub identifier: Fragment,
290	pub namespace: ResolvedNamespace,
291	pub def: Series,
292}
293
294impl ResolvedSeries {
295	pub fn new(identifier: Fragment, namespace: ResolvedNamespace, def: Series) -> Self {
296		Self(Arc::new(ResolvedSeriesInner {
297			identifier,
298			namespace,
299			def,
300		}))
301	}
302
303	pub fn name(&self) -> &str {
304		&self.0.def.name
305	}
306
307	pub fn def(&self) -> &Series {
308		&self.0.def
309	}
310
311	pub fn namespace(&self) -> &ResolvedNamespace {
312		&self.0.namespace
313	}
314
315	pub fn identifier(&self) -> &Fragment {
316		&self.0.identifier
317	}
318
319	pub fn fully_qualified_name(&self) -> String {
320		format!("{}::{}", self.0.namespace.name(), self.name())
321	}
322
323	pub fn columns(&self) -> &[Column] {
324		&self.0.def.columns
325	}
326
327	pub fn find_column(&self, name: &str) -> Option<&Column> {
328		self.0.def.columns.iter().find(|c| c.name == name)
329	}
330
331	pub fn to_static(&self) -> ResolvedSeries {
332		ResolvedSeries(Arc::new(ResolvedSeriesInner {
333			identifier: Fragment::internal(self.0.identifier.text()),
334			namespace: self.0.namespace.clone(),
335			def: self.0.def.clone(),
336		}))
337	}
338}
339
340#[derive(Debug, Clone)]
341pub struct ResolvedQueue(Arc<ResolvedQueueInner>);
342
343#[derive(Debug)]
344struct ResolvedQueueInner {
345	pub identifier: Fragment,
346	pub namespace: ResolvedNamespace,
347	pub def: Queue,
348}
349
350impl ResolvedQueue {
351	pub fn new(identifier: Fragment, namespace: ResolvedNamespace, def: Queue) -> Self {
352		Self(Arc::new(ResolvedQueueInner {
353			identifier,
354			namespace,
355			def,
356		}))
357	}
358
359	pub fn name(&self) -> &str {
360		&self.0.def.name
361	}
362
363	pub fn def(&self) -> &Queue {
364		&self.0.def
365	}
366
367	pub fn namespace(&self) -> &ResolvedNamespace {
368		&self.0.namespace
369	}
370
371	pub fn identifier(&self) -> &Fragment {
372		&self.0.identifier
373	}
374
375	pub fn fully_qualified_name(&self) -> String {
376		format!("{}::{}", self.0.namespace.name(), self.name())
377	}
378
379	pub fn columns(&self) -> &[Column] {
380		&self.0.def.columns
381	}
382
383	pub fn find_column(&self, name: &str) -> Option<&Column> {
384		self.0.def.columns.iter().find(|c| c.name == name)
385	}
386
387	pub fn to_static(&self) -> ResolvedQueue {
388		ResolvedQueue(Arc::new(ResolvedQueueInner {
389			identifier: Fragment::internal(self.0.identifier.text()),
390			namespace: self.0.namespace.clone(),
391			def: self.0.def.clone(),
392		}))
393	}
394}
395
396#[derive(Debug, Clone)]
397pub struct ResolvedView(Arc<ResolvedViewInner>);
398
399#[derive(Debug)]
400struct ResolvedViewInner {
401	pub identifier: Fragment,
402	pub namespace: ResolvedNamespace,
403	pub def: View,
404}
405
406impl ResolvedView {
407	pub fn new(identifier: Fragment, namespace: ResolvedNamespace, def: View) -> Self {
408		Self(Arc::new(ResolvedViewInner {
409			identifier,
410			namespace,
411			def,
412		}))
413	}
414
415	pub fn name(&self) -> &str {
416		self.0.def.name()
417	}
418
419	pub fn def(&self) -> &View {
420		&self.0.def
421	}
422
423	pub fn namespace(&self) -> &ResolvedNamespace {
424		&self.0.namespace
425	}
426
427	pub fn identifier(&self) -> &Fragment {
428		&self.0.identifier
429	}
430
431	pub fn columns(&self) -> &[Column] {
432		self.0.def.columns()
433	}
434
435	pub fn fully_qualified_name(&self) -> String {
436		format!("{}::{}", self.0.namespace.name(), self.name())
437	}
438
439	pub fn to_static(&self) -> ResolvedView {
440		ResolvedView(Arc::new(ResolvedViewInner {
441			identifier: Fragment::internal(self.0.identifier.text()),
442			namespace: self.0.namespace.clone(),
443			def: self.0.def.clone(),
444		}))
445	}
446}
447
448#[derive(Debug, Clone)]
449pub struct ResolvedDeferredView(Arc<ResolvedDeferredViewInner>);
450
451#[derive(Debug)]
452struct ResolvedDeferredViewInner {
453	pub identifier: Fragment,
454	pub namespace: ResolvedNamespace,
455	pub def: View,
456}
457
458impl ResolvedDeferredView {
459	pub fn new(identifier: Fragment, namespace: ResolvedNamespace, def: View) -> Self {
460		Self(Arc::new(ResolvedDeferredViewInner {
461			identifier,
462			namespace,
463			def,
464		}))
465	}
466
467	pub fn name(&self) -> &str {
468		self.0.def.name()
469	}
470
471	pub fn def(&self) -> &View {
472		&self.0.def
473	}
474
475	pub fn namespace(&self) -> &ResolvedNamespace {
476		&self.0.namespace
477	}
478
479	pub fn identifier(&self) -> &Fragment {
480		&self.0.identifier
481	}
482
483	pub fn columns(&self) -> &[Column] {
484		self.0.def.columns()
485	}
486
487	pub fn to_static(&self) -> ResolvedDeferredView {
488		ResolvedDeferredView(Arc::new(ResolvedDeferredViewInner {
489			identifier: Fragment::internal(self.0.identifier.text()),
490			namespace: self.0.namespace.clone(),
491			def: self.0.def.clone(),
492		}))
493	}
494}
495
496#[derive(Debug, Clone)]
497pub struct ResolvedTransactionalView(Arc<ResolvedTransactionalViewInner>);
498
499#[derive(Debug)]
500struct ResolvedTransactionalViewInner {
501	pub identifier: Fragment,
502	pub namespace: ResolvedNamespace,
503	pub def: View,
504}
505
506impl ResolvedTransactionalView {
507	pub fn new(identifier: Fragment, namespace: ResolvedNamespace, def: View) -> Self {
508		Self(Arc::new(ResolvedTransactionalViewInner {
509			identifier,
510			namespace,
511			def,
512		}))
513	}
514
515	pub fn name(&self) -> &str {
516		self.0.def.name()
517	}
518
519	pub fn def(&self) -> &View {
520		&self.0.def
521	}
522
523	pub fn namespace(&self) -> &ResolvedNamespace {
524		&self.0.namespace
525	}
526
527	pub fn identifier(&self) -> &Fragment {
528		&self.0.identifier
529	}
530
531	pub fn columns(&self) -> &[Column] {
532		self.0.def.columns()
533	}
534
535	pub fn to_static(&self) -> ResolvedTransactionalView {
536		ResolvedTransactionalView(Arc::new(ResolvedTransactionalViewInner {
537			identifier: Fragment::internal(self.0.identifier.text()),
538			namespace: self.0.namespace.clone(),
539			def: self.0.def.clone(),
540		}))
541	}
542}
543
544#[derive(Debug, Clone)]
545pub struct ResolvedSequence(Arc<ResolvedSequenceInner>);
546
547#[derive(Debug)]
548struct ResolvedSequenceInner {
549	pub identifier: Fragment,
550	pub namespace: ResolvedNamespace,
551	pub def: Sequence,
552}
553
554impl ResolvedSequence {
555	pub fn new(identifier: Fragment, namespace: ResolvedNamespace, def: Sequence) -> Self {
556		Self(Arc::new(ResolvedSequenceInner {
557			identifier,
558			namespace,
559			def,
560		}))
561	}
562
563	pub fn identifier(&self) -> &Fragment {
564		&self.0.identifier
565	}
566
567	pub fn namespace(&self) -> &ResolvedNamespace {
568		&self.0.namespace
569	}
570
571	pub fn def(&self) -> &Sequence {
572		&self.0.def
573	}
574}
575
576#[derive(Debug, Clone)]
577pub struct ResolvedIndex(Arc<ResolvedIndexInner>);
578
579#[derive(Debug)]
580struct ResolvedIndexInner {
581	pub identifier: Fragment,
582	pub table: ResolvedTable,
583	pub def: Index,
584}
585
586impl ResolvedIndex {
587	pub fn new(identifier: Fragment, table: ResolvedTable, def: Index) -> Self {
588		Self(Arc::new(ResolvedIndexInner {
589			identifier,
590			table,
591			def,
592		}))
593	}
594
595	pub fn identifier(&self) -> &Fragment {
596		&self.0.identifier
597	}
598
599	pub fn table(&self) -> &ResolvedTable {
600		&self.0.table
601	}
602
603	pub fn def(&self) -> &Index {
604		&self.0.def
605	}
606}
607
608#[derive(Debug, Clone)]
609pub struct ResolvedFunction(Arc<ResolvedFunctionInner>);
610
611#[derive(Debug)]
612struct ResolvedFunctionInner {
613	pub identifier: Fragment,
614	pub namespace: Vec<ResolvedNamespace>,
615	pub def: Function,
616}
617
618impl ResolvedFunction {
619	pub fn new(identifier: Fragment, namespace: Vec<ResolvedNamespace>, def: Function) -> Self {
620		Self(Arc::new(ResolvedFunctionInner {
621			identifier,
622			namespace,
623			def,
624		}))
625	}
626
627	pub fn identifier(&self) -> &Fragment {
628		&self.0.identifier
629	}
630
631	pub fn namespace(&self) -> &[ResolvedNamespace] {
632		&self.0.namespace
633	}
634
635	pub fn def(&self) -> &Function {
636		&self.0.def
637	}
638}
639
640#[derive(Debug, Clone)]
641pub enum ResolvedObject {
642	Table(ResolvedTable),
643	TableVirtual(ResolvedTableVirtual),
644	View(ResolvedView),
645	DeferredView(ResolvedDeferredView),
646	TransactionalView(ResolvedTransactionalView),
647	RingBuffer(ResolvedRingBuffer),
648	Dictionary(ResolvedDictionary),
649	Series(ResolvedSeries),
650	Queue(ResolvedQueue),
651}
652
653impl ResolvedObject {
654	pub fn identifier(&self) -> &Fragment {
655		match self {
656			Self::Table(t) => t.identifier(),
657			Self::TableVirtual(t) => t.identifier(),
658			Self::View(v) => v.identifier(),
659			Self::DeferredView(v) => v.identifier(),
660			Self::TransactionalView(v) => v.identifier(),
661			Self::RingBuffer(r) => r.identifier(),
662			Self::Dictionary(d) => d.identifier(),
663			Self::Series(s) => s.identifier(),
664			Self::Queue(q) => q.identifier(),
665		}
666	}
667
668	pub fn name(&self) -> &str {
669		match self {
670			Self::Table(t) => t.name(),
671			Self::TableVirtual(t) => t.name(),
672			Self::View(v) => v.name(),
673			Self::DeferredView(v) => v.name(),
674			Self::TransactionalView(v) => v.name(),
675			Self::RingBuffer(r) => r.name(),
676			Self::Dictionary(d) => d.name(),
677			Self::Series(s) => s.name(),
678			Self::Queue(q) => q.name(),
679		}
680	}
681
682	pub fn namespace(&self) -> Option<&ResolvedNamespace> {
683		match self {
684			Self::Table(t) => Some(t.namespace()),
685			Self::TableVirtual(t) => Some(t.namespace()),
686			Self::View(v) => Some(v.namespace()),
687			Self::DeferredView(v) => Some(v.namespace()),
688			Self::TransactionalView(v) => Some(v.namespace()),
689			Self::RingBuffer(r) => Some(r.namespace()),
690			Self::Dictionary(d) => Some(d.namespace()),
691			Self::Series(s) => Some(s.namespace()),
692			Self::Queue(q) => Some(q.namespace()),
693		}
694	}
695
696	pub fn supports_indexes(&self) -> bool {
697		matches!(self, Self::Table(_))
698	}
699
700	pub fn supports_mutations(&self) -> bool {
701		matches!(self, Self::Table(_) | Self::RingBuffer(_) | Self::Series(_))
702	}
703
704	pub fn columns(&self) -> &[Column] {
705		match self {
706			Self::Table(t) => t.columns(),
707			Self::TableVirtual(t) => t.columns(),
708			Self::View(v) => v.columns(),
709			Self::DeferredView(v) => v.columns(),
710			Self::TransactionalView(v) => v.columns(),
711			Self::RingBuffer(r) => r.columns(),
712			Self::Dictionary(_d) => unreachable!(),
713			Self::Series(s) => s.columns(),
714			Self::Queue(q) => q.columns(),
715		}
716	}
717
718	pub fn find_column(&self, name: &str) -> Option<&Column> {
719		self.columns().iter().find(|c| c.name == name)
720	}
721
722	pub fn kind_name(&self) -> &'static str {
723		match self {
724			Self::Table(_) => "table",
725			Self::TableVirtual(_) => "virtual table",
726			Self::View(_) => "view",
727			Self::DeferredView(_) => "deferred view",
728			Self::TransactionalView(_) => "transactional view",
729			Self::RingBuffer(_) => "ring buffer",
730			Self::Dictionary(_) => "dictionary",
731			Self::Series(_) => "series",
732			Self::Queue(_) => "queue",
733		}
734	}
735
736	pub fn fully_qualified_name(&self) -> Option<String> {
737		match self {
738			Self::Table(t) => Some(t.fully_qualified_name()),
739			Self::View(v) => Some(v.fully_qualified_name()),
740			Self::DeferredView(v) => Some(format!("{}::{}", v.namespace().name(), v.name())),
741			Self::TransactionalView(v) => Some(format!("{}::{}", v.namespace().name(), v.name())),
742			Self::TableVirtual(t) => Some(format!("{}::{}", t.namespace().name(), t.name())),
743			Self::RingBuffer(r) => Some(r.fully_qualified_name()),
744			Self::Dictionary(d) => Some(d.fully_qualified_name()),
745			Self::Series(s) => Some(s.fully_qualified_name()),
746			Self::Queue(q) => Some(q.fully_qualified_name()),
747		}
748	}
749
750	pub fn as_table(&self) -> Option<&ResolvedTable> {
751		match self {
752			Self::Table(t) => Some(t),
753			_ => None,
754		}
755	}
756
757	pub fn as_view(&self) -> Option<&ResolvedView> {
758		match self {
759			Self::View(v) => Some(v),
760			_ => None,
761		}
762	}
763
764	pub fn as_ringbuffer(&self) -> Option<&ResolvedRingBuffer> {
765		match self {
766			Self::RingBuffer(r) => Some(r),
767			_ => None,
768		}
769	}
770
771	pub fn as_dictionary(&self) -> Option<&ResolvedDictionary> {
772		match self {
773			Self::Dictionary(d) => Some(d),
774			_ => None,
775		}
776	}
777
778	pub fn as_series(&self) -> Option<&ResolvedSeries> {
779		match self {
780			Self::Series(s) => Some(s),
781			_ => None,
782		}
783	}
784
785	pub fn as_queue(&self) -> Option<&ResolvedQueue> {
786		match self {
787			Self::Queue(q) => Some(q),
788			_ => None,
789		}
790	}
791}
792
793#[derive(Debug, Clone)]
794pub struct ResolvedColumn(Arc<ResolvedColumnInner>);
795
796#[derive(Debug)]
797struct ResolvedColumnInner {
798	pub identifier: Fragment,
799
800	pub object: ResolvedObject,
801
802	pub def: Column,
803}
804
805impl ResolvedColumn {
806	pub fn new(identifier: Fragment, object: ResolvedObject, def: Column) -> Self {
807		Self(Arc::new(ResolvedColumnInner {
808			identifier,
809			object,
810			def,
811		}))
812	}
813
814	pub fn name(&self) -> &str {
815		&self.0.def.name
816	}
817
818	pub fn def(&self) -> &Column {
819		&self.0.def
820	}
821
822	pub fn identifier(&self) -> &Fragment {
823		&self.0.identifier
824	}
825
826	pub fn object(&self) -> &ResolvedObject {
827		&self.0.object
828	}
829
830	pub fn type_constraint(&self) -> &TypeConstraint {
831		&self.0.def.constraint
832	}
833
834	pub fn column_type(&self) -> ValueType {
835		self.0.def.constraint.get_type()
836	}
837
838	pub fn properties(&self) -> Vec<ColumnPropertyKind> {
839		self.0.def.properties.iter().map(|p| p.property.clone()).collect()
840	}
841
842	pub fn is_auto_increment(&self) -> bool {
843		self.0.def.auto_increment
844	}
845
846	pub fn namespace(&self) -> Option<&ResolvedNamespace> {
847		self.0.object.namespace()
848	}
849
850	pub fn qualified_name(&self) -> String {
851		match self.0.object.fully_qualified_name() {
852			Some(object_name) => {
853				format!("{}.{}", object_name, self.name())
854			}
855			None => format!("{}.{}", self.0.object.identifier().text(), self.name()),
856		}
857	}
858
859	pub fn fragment(&self) -> &Fragment {
860		&self.0.identifier
861	}
862
863	pub fn to_static(&self) -> ResolvedColumn {
864		ResolvedColumn(Arc::new(ResolvedColumnInner {
865			identifier: Fragment::internal(self.0.identifier.text()),
866			object: self.0.object.clone(),
867			def: self.0.def.clone(),
868		}))
869	}
870}
871
872pub fn resolved_column_to_number_descriptor(column: &ResolvedColumn) -> NumberOutOfRangeDescriptor {
873	let (namespace, table) = match column.object() {
874		ResolvedObject::Table(table) => {
875			(Some(table.namespace().name().to_string()), Some(table.name().to_string()))
876		}
877		ResolvedObject::TableVirtual(table) => {
878			(Some(table.namespace().name().to_string()), Some(table.name().to_string()))
879		}
880		ResolvedObject::RingBuffer(rb) => {
881			(Some(rb.namespace().name().to_string()), Some(rb.name().to_string()))
882		}
883		ResolvedObject::View(view) => {
884			(Some(view.namespace().name().to_string()), Some(view.name().to_string()))
885		}
886		ResolvedObject::DeferredView(view) => {
887			(Some(view.namespace().name().to_string()), Some(view.name().to_string()))
888		}
889		ResolvedObject::TransactionalView(view) => {
890			(Some(view.namespace().name().to_string()), Some(view.name().to_string()))
891		}
892		ResolvedObject::Dictionary(dict) => {
893			(Some(dict.namespace().name().to_string()), Some(dict.name().to_string()))
894		}
895		ResolvedObject::Series(series) => {
896			(Some(series.namespace().name().to_string()), Some(series.name().to_string()))
897		}
898		ResolvedObject::Queue(queue) => {
899			(Some(queue.namespace().name().to_string()), Some(queue.name().to_string()))
900		}
901	};
902
903	NumberOutOfRangeDescriptor {
904		namespace,
905		table,
906		column: Some(column.name().to_string()),
907		column_type: Some(column.column_type()),
908	}
909}
910
911#[derive(Debug, Clone, Serialize, Deserialize)]
912pub struct Sequence {
913	pub name: String,
914	pub current_value: i64,
915	pub increment: i64,
916}
917
918#[derive(Debug, Clone, Serialize, Deserialize)]
919pub struct Index {
920	pub name: String,
921	pub columns: Vec<String>,
922	pub unique: bool,
923}
924
925#[derive(Debug, Clone, Serialize, Deserialize)]
926pub struct Function {
927	pub name: String,
928	pub parameters: Vec<String>,
929	pub return_type: String,
930}
931
932#[cfg(test)]
933pub mod tests {
934	use reifydb_value::{
935		fragment::Fragment,
936		value::{constraint::TypeConstraint, value_type::ValueType},
937	};
938
939	use super::*;
940	use crate::{
941		common::TimeSource,
942		interface::catalog::{
943			column::ColumnIndex,
944			id::{ColumnId, NamespaceId, TableId},
945		},
946	};
947
948	fn test_namespace_def() -> Namespace {
949		Namespace::Local {
950			id: NamespaceId::SYSTEM,
951			name: "public".to_string(),
952			local_name: "public".to_string(),
953			parent_id: NamespaceId::ROOT,
954		}
955	}
956
957	fn test_table() -> Table {
958		Table {
959			id: TableId(1),
960			namespace: NamespaceId::SYSTEM,
961			name: "users".to_string(),
962			columns: vec![
963				Column {
964					id: ColumnId(1),
965					name: "id".to_string(),
966					constraint: TypeConstraint::unconstrained(ValueType::Int8),
967					properties: vec![],
968					index: ColumnIndex(0),
969					auto_increment: false,
970					dictionary_id: None,
971				},
972				Column {
973					id: ColumnId(2),
974					name: "name".to_string(),
975					constraint: TypeConstraint::unconstrained(ValueType::Utf8),
976					properties: vec![],
977					index: ColumnIndex(1),
978					auto_increment: false,
979					dictionary_id: None,
980				},
981			],
982			primary_key: None,
983			partition_by: vec![],
984			time: TimeSource::Processing,
985		}
986	}
987
988	#[test]
989	fn test_resolved_namespace() {
990		let identifier = Fragment::testing("public");
991		let def = test_namespace_def();
992		let resolved = ResolvedNamespace::new(identifier, def);
993
994		assert_eq!(resolved.name(), "public");
995		assert_eq!(resolved.fragment().text(), "public");
996	}
997
998	#[test]
999	fn test_resolved_table() {
1000		let namespace_ident = Fragment::testing("public");
1001		let namespace = ResolvedNamespace::new(namespace_ident, test_namespace_def());
1002
1003		let table_ident = Fragment::testing("users");
1004		let table = ResolvedTable::new(table_ident, namespace.clone(), test_table());
1005
1006		assert_eq!(table.name(), "users");
1007		assert_eq!(table.fully_qualified_name(), "public::users");
1008		assert_eq!(table.columns().len(), 2);
1009		assert!(table.find_column("id").is_some());
1010		assert!(table.find_column("nonexistent").is_none());
1011	}
1012
1013	#[test]
1014	fn test_resolved_object_enum() {
1015		let namespace = ResolvedNamespace::new(Fragment::testing("public"), test_namespace_def());
1016
1017		let table = ResolvedTable::new(Fragment::testing("users"), namespace, test_table());
1018
1019		let object = ResolvedObject::Table(table);
1020
1021		assert!(object.supports_indexes());
1022		assert!(object.supports_mutations());
1023		assert_eq!(object.kind_name(), "table");
1024		assert_eq!(object.fully_qualified_name(), Some("public::users".to_string()));
1025		assert!(object.as_table().is_some());
1026		assert!(object.as_view().is_none());
1027	}
1028
1029	#[test]
1030	fn test_resolved_column() {
1031		let namespace = ResolvedNamespace::new(Fragment::testing("public"), test_namespace_def());
1032
1033		let table = ResolvedTable::new(Fragment::testing("users"), namespace, test_table());
1034
1035		let object = ResolvedObject::Table(table);
1036
1037		let column_ident = Fragment::testing("id");
1038
1039		let column = Column {
1040			id: ColumnId(1),
1041			name: "id".to_string(),
1042			constraint: TypeConstraint::unconstrained(ValueType::Int8),
1043			properties: vec![],
1044			index: ColumnIndex(0),
1045			auto_increment: false,
1046			dictionary_id: None,
1047		};
1048
1049		let column = ResolvedColumn::new(column_ident, object, column);
1050
1051		assert_eq!(column.name(), "id");
1052		assert_eq!(column.type_constraint(), &TypeConstraint::unconstrained(ValueType::Int8));
1053		assert!(!column.is_auto_increment());
1054		assert_eq!(column.qualified_name(), "public::users.id");
1055	}
1056}