Skip to main content

reifydb_core/interface/
resolved.rs

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