Skip to main content

reifydb_rql/
nodes.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use std::{collections, fmt};
5
6use reifydb_catalog::catalog::{
7	ringbuffer::RingBufferColumnToCreate, series::SeriesColumnToCreate, table::TableColumnToCreate,
8	view::ViewColumnToCreate,
9};
10use reifydb_core::{
11	common::{JoinType, WindowKind},
12	interface::{
13		catalog::{
14			binding::{BindingFormat, BindingProtocol},
15			id::{HandlerId, NamespaceId, ProcedureId, RingBufferId, SeriesId, TableId, TestId, ViewId},
16			namespace::Namespace,
17			procedure::{ProcedureParam, RqlTrigger},
18			property::ColumnPropertyKind,
19			series::SeriesKey,
20		},
21		resolved::{
22			ResolvedColumn, ResolvedDictionary, ResolvedNamespace, ResolvedRingBuffer, ResolvedSequence,
23			ResolvedSeries, ResolvedShape, ResolvedTable, ResolvedTableVirtual, ResolvedView,
24		},
25	},
26	row::RowTtl,
27	sort::{SortDirection, SortKey},
28};
29use reifydb_type::{
30	fragment::Fragment,
31	value::{
32		constraint::TypeConstraint, dictionary::DictionaryId, duration::Duration, sumtype::SumTypeId,
33		r#type::Type,
34	},
35};
36
37use crate::{
38	expression::{AliasExpression, Expression, VariableExpression},
39	query::QueryPlan,
40};
41
42/// Owned primary key definition for physical plan nodes (materialized from bump-allocated logical plan)
43#[derive(Debug, Clone)]
44pub struct PrimaryKey {
45	pub columns: Vec<PrimaryKeyColumn>,
46}
47
48/// Owned primary key column for physical plan nodes
49#[derive(Debug, Clone)]
50pub struct PrimaryKeyColumn {
51	pub column: Fragment,
52	pub order: Option<SortDirection>,
53}
54
55#[derive(Debug, Clone)]
56pub enum PhysicalPlan {
57	CreateDeferredView(CreateDeferredViewNode),
58	CreateTransactionalView(CreateTransactionalViewNode),
59	CreateNamespace(CreateNamespaceNode),
60	CreateRemoteNamespace(CreateRemoteNamespaceNode),
61	CreateTable(CreateTableNode),
62	CreateRingBuffer(CreateRingBufferNode),
63	CreateDictionary(CreateDictionaryNode),
64	CreateSumType(CreateSumTypeNode),
65	CreateSubscription(CreateSubscriptionNode),
66	CreatePrimaryKey(CreatePrimaryKeyNode),
67	CreateColumnProperty(CreateColumnPropertyNode),
68	CreateProcedure(CreateProcedureNode),
69	CreateSeries(CreateSeriesNode),
70	CreateEvent(CreateEventNode),
71	CreateTag(CreateTagNode),
72	CreateTest(CreateTestNode),
73	RunTests(RunTestsNode),
74
75	CreateMigration(CreateMigrationNode),
76	Migrate(MigrateNode),
77	RollbackMigration(RollbackMigrationNode),
78	Dispatch(DispatchNode),
79	// Alter
80	AlterSequence(AlterSequenceNode),
81	AlterTable(AlterTableNode),
82	AlterRemoteNamespace(AlterRemoteNamespaceNode),
83	// Mutate
84	Delete(DeleteTableNode),
85	DeleteRingBuffer(DeleteRingBufferNode),
86	InsertTable(InsertTableNode),
87	InsertRingBuffer(InsertRingBufferNode),
88	InsertDictionary(InsertDictionaryNode),
89	Update(UpdateTableNode),
90	UpdateRingBuffer(UpdateRingBufferNode),
91	UpdateSeries(UpdateSeriesNode),
92	// Variable assignment
93	Declare(DeclareNode),
94	Assign(AssignNode),
95	Append(AppendPhysicalNode),
96	// Variable resolution
97	Variable(VariableNode),
98	Environment(EnvironmentNode),
99	// Control flow
100	Conditional(ConditionalNode),
101	Loop(LoopPhysicalNode),
102	While(WhilePhysicalNode),
103	For(ForPhysicalNode),
104	Break,
105	Continue,
106	// User-defined functions
107	DefineFunction(DefineFunctionNode),
108	Return(ReturnNode),
109	CallFunction(CallFunctionNode),
110
111	// Query
112	Aggregate(AggregateNode),
113	Distinct(DistinctNode),
114	Filter(FilterNode),
115	IndexScan(IndexScanNode),
116	// Row-number optimized access
117	RowPointLookup(RowPointLookupNode),
118	RowListLookup(RowListLookupNode),
119	RowRangeScan(RowRangeScanNode),
120	JoinInner(JoinInnerNode),
121	JoinLeft(JoinLeftNode),
122	JoinNatural(JoinNaturalNode),
123	Take(TakeNode),
124	Sort(SortNode),
125	Map(MapNode),
126	Extend(ExtendNode),
127	Patch(PatchNode),
128	Apply(ApplyNode),
129	InlineData(InlineDataNode),
130	RemoteScan(RemoteScanNode),
131	TableScan(TableScanNode),
132	TableVirtualScan(TableVirtualScanNode),
133	ViewScan(ViewScanNode),
134	RingBufferScan(RingBufferScanNode),
135	DictionaryScan(DictionaryScanNode),
136	SeriesScan(SeriesScanNode),
137	// Series DML
138	InsertSeries(InsertSeriesNode),
139	DeleteSeries(DeleteSeriesNode),
140	Generator(GeneratorNode),
141	Window(WindowNode),
142	// Auto-scalarization for 1x1 frames
143	Scalarize(ScalarizeNode),
144	// Auth/Permissions
145	CreateIdentity(CreateIdentityNode),
146	CreateRole(CreateRoleNode),
147	Grant(GrantNode),
148	Revoke(RevokeNode),
149	DropIdentity(DropIdentityNode),
150	DropRole(DropRoleNode),
151	CreateAuthentication(CreateAuthenticationNode),
152	DropAuthentication(DropAuthenticationNode),
153	CreatePolicy(CreatePolicyNode),
154	AlterPolicy(AlterPolicyNode),
155	DropPolicy(DropPolicyNode),
156}
157
158#[derive(Debug, Clone)]
159pub enum CompiledViewStorageKind {
160	Table,
161	RingBuffer {
162		capacity: u64,
163		propagate_evictions: bool,
164		partition_by: Vec<String>,
165	},
166	Series {
167		key: SeriesKey,
168	},
169}
170
171#[derive(Debug, Clone)]
172pub struct CreateDeferredViewNode {
173	pub namespace: Namespace, // FIXME REsolvedNamespace
174	pub view: Fragment,
175	pub if_not_exists: bool,
176	pub columns: Vec<ViewColumnToCreate>,
177	pub as_clause: Box<QueryPlan>,
178	pub storage_kind: CompiledViewStorageKind,
179	pub tick: Option<Duration>,
180	pub ttl: Option<RowTtl>,
181}
182
183#[derive(Debug, Clone)]
184pub struct CreateTransactionalViewNode {
185	pub namespace: Namespace, // FIXME REsolvedNamespace
186	pub view: Fragment,
187	pub if_not_exists: bool,
188	pub columns: Vec<ViewColumnToCreate>,
189	pub as_clause: Box<QueryPlan>,
190	pub storage_kind: CompiledViewStorageKind,
191	pub tick: Option<Duration>,
192	pub ttl: Option<RowTtl>,
193}
194
195#[derive(Debug, Clone)]
196pub struct CreateNamespaceNode {
197	pub segments: Vec<Fragment>,
198	pub if_not_exists: bool,
199}
200
201#[derive(Debug, Clone)]
202pub struct CreateRemoteNamespaceNode {
203	pub segments: Vec<Fragment>,
204	pub if_not_exists: bool,
205	pub grpc: Fragment,
206	pub token: Option<Fragment>,
207}
208
209#[derive(Debug, Clone)]
210pub struct AlterRemoteNamespaceNode {
211	pub namespace: Fragment,
212	pub grpc: Fragment,
213}
214
215#[derive(Debug, Clone)]
216pub struct CreateTableNode {
217	pub namespace: ResolvedNamespace,
218	pub table: Fragment,
219	pub if_not_exists: bool,
220	pub columns: Vec<TableColumnToCreate>,
221	pub ttl: Option<RowTtl>,
222}
223
224#[derive(Debug, Clone)]
225pub struct CreateRingBufferNode {
226	pub namespace: ResolvedNamespace,
227	pub ringbuffer: Fragment,
228	pub if_not_exists: bool,
229	pub columns: Vec<RingBufferColumnToCreate>,
230	pub capacity: u64,
231	pub partition_by: Vec<String>,
232	pub ttl: Option<RowTtl>,
233}
234
235#[derive(Debug, Clone)]
236pub struct CreateDictionaryNode {
237	pub namespace: Namespace,
238	pub dictionary: Fragment,
239	pub if_not_exists: bool,
240	pub value_type: Type,
241	pub id_type: Type,
242}
243
244#[derive(Debug, Clone)]
245pub struct CreateSumTypeNode {
246	pub namespace: Namespace,
247	pub name: Fragment,
248	pub if_not_exists: bool,
249	pub variants: Vec<CreateSumTypeVariant>,
250}
251
252#[derive(Debug, Clone)]
253pub struct CreateSumTypeVariant {
254	pub name: String,
255	pub columns: Vec<CreateSumTypeColumn>,
256}
257
258#[derive(Debug, Clone)]
259pub struct CreateSumTypeColumn {
260	pub name: String,
261	pub column_type: TypeConstraint,
262}
263
264#[derive(Debug, Clone)]
265pub struct SubscriptionColumnToCreate {
266	pub name: String,
267	pub ty: Type,
268}
269
270#[derive(Debug, Clone)]
271pub struct CreateSubscriptionNode {
272	pub columns: Vec<SubscriptionColumnToCreate>,
273	pub as_clause: Option<Box<QueryPlan>>,
274}
275
276#[derive(Debug, Clone)]
277pub struct AlterSequenceNode {
278	pub sequence: ResolvedSequence,
279	pub column: ResolvedColumn,
280	pub value: Expression,
281}
282
283#[derive(Debug, Clone)]
284pub struct AlterTableNode {
285	pub namespace: ResolvedNamespace,
286	pub table: Fragment,
287	pub action: AlterTableAction,
288}
289
290#[derive(Debug, Clone)]
291pub enum AlterTableAction {
292	AddColumn {
293		column: TableColumnToCreate,
294	},
295	DropColumn {
296		column: Fragment,
297	},
298	RenameColumn {
299		old_name: Fragment,
300		new_name: Fragment,
301	},
302}
303
304// Create Primary Key node
305#[derive(Debug, Clone)]
306pub struct CreatePrimaryKeyNode {
307	pub namespace: ResolvedNamespace,
308	pub table: Fragment,
309	pub columns: Vec<PrimaryKeyColumn>,
310}
311
312// Create Procedure node
313#[derive(Debug, Clone)]
314pub struct CreateProcedureNode {
315	pub namespace: Namespace,
316	pub name: Fragment,
317	pub params: Vec<ProcedureParam>,
318	pub body_source: String,
319	/// Ignored when `is_test = true` (test procedures have no trigger).
320	pub trigger: RqlTrigger,
321	pub is_test: bool,
322}
323
324/// Physical node for CREATE SERIES
325#[derive(Debug, Clone)]
326pub struct CreateSeriesNode {
327	pub namespace: ResolvedNamespace,
328	pub series: Fragment,
329	pub columns: Vec<SeriesColumnToCreate>,
330	pub tag: Option<SumTypeId>,
331	pub key: SeriesKey,
332	pub ttl: Option<RowTtl>,
333}
334
335/// Physical node for CREATE EVENT
336#[derive(Debug, Clone)]
337pub struct CreateEventNode {
338	pub namespace: Namespace,
339	pub name: Fragment,
340	pub variants: Vec<CreateSumTypeVariant>,
341}
342
343/// Physical node for CREATE TAG
344#[derive(Debug, Clone)]
345pub struct CreateTagNode {
346	pub namespace: Namespace,
347	pub name: Fragment,
348	pub variants: Vec<CreateSumTypeVariant>,
349}
350
351/// A resolved key-value config pair
352#[derive(Debug, Clone)]
353pub struct ConfigPair {
354	pub key: Fragment,
355	pub value: Fragment,
356}
357
358/// Physical node for CREATE SOURCE
359#[derive(Debug, Clone)]
360pub struct CreateSourceNode {
361	pub namespace: Namespace,
362	pub name: Fragment,
363	pub connector: Fragment,
364	pub config: Vec<ConfigPair>,
365	pub target_namespace: Namespace,
366	pub target_name: Fragment,
367}
368
369/// Physical node for CREATE SINK
370#[derive(Debug, Clone)]
371pub struct CreateSinkNode {
372	pub namespace: Namespace,
373	pub name: Fragment,
374	pub source_namespace: Namespace,
375	pub source_name: Fragment,
376	pub connector: Fragment,
377	pub config: Vec<ConfigPair>,
378}
379
380/// Physical node for DROP SOURCE
381#[derive(Debug, Clone)]
382pub struct DropSourceNode {
383	pub if_exists: bool,
384	pub namespace: Namespace,
385	pub name: Fragment,
386	pub cascade: bool,
387}
388
389/// Physical node for DROP SINK
390#[derive(Debug, Clone)]
391pub struct DropSinkNode {
392	pub if_exists: bool,
393	pub namespace: Namespace,
394	pub name: Fragment,
395	pub cascade: bool,
396}
397
398/// Physical node for CREATE BINDING
399#[derive(Debug, Clone)]
400pub struct CreateBindingNode {
401	pub namespace: Namespace,
402	pub name: Fragment,
403	pub procedure_id: ProcedureId,
404	pub protocol: BindingProtocol,
405	pub format: BindingFormat,
406}
407
408/// Physical node for DROP BINDING
409#[derive(Debug, Clone)]
410pub struct DropBindingNode {
411	pub namespace: Namespace,
412	pub name: Fragment,
413	pub if_exists: bool,
414}
415
416/// Physical node for DROP PROCEDURE
417#[derive(Debug, Clone)]
418pub struct DropProcedureNode {
419	pub namespace_name: Fragment,
420	pub procedure_name: Fragment,
421	pub procedure_id: Option<ProcedureId>,
422	pub if_exists: bool,
423}
424
425/// Physical node for DROP HANDLER
426#[derive(Debug, Clone)]
427pub struct DropHandlerNode {
428	pub namespace_name: Fragment,
429	pub handler_name: Fragment,
430	pub procedure_id: Option<ProcedureId>,
431	pub handler_id: Option<HandlerId>,
432	pub if_exists: bool,
433}
434
435/// Physical node for DROP TEST
436#[derive(Debug, Clone)]
437pub struct DropTestNode {
438	pub namespace_name: Fragment,
439	pub test_name: Fragment,
440	pub test_id: Option<TestId>,
441	pub if_exists: bool,
442}
443
444// Assert Block node (multi-statement ASSERT or ASSERT ERROR)
445#[derive(Debug, Clone)]
446pub struct AssertBlockNode {
447	pub rql: String,
448	pub expect_error: bool,
449	pub message: Option<String>,
450}
451
452// Create Test node
453#[derive(Debug, Clone)]
454pub struct CreateTestNode {
455	pub namespace: Namespace,
456	pub name: Fragment,
457	pub cases: Option<String>,
458	pub body_source: String,
459}
460
461// Run Tests node
462#[derive(Debug, Clone)]
463pub struct RunTestsNode {
464	pub scope: RunTestsScope,
465}
466
467#[derive(Debug, Clone)]
468pub enum RunTestsScope {
469	All,
470	Namespace(ResolvedNamespace),
471	Single(ResolvedNamespace, String),
472}
473
474/// Physical node for CREATE MIGRATION
475#[derive(Debug, Clone)]
476pub struct CreateMigrationNode {
477	pub name: String,
478	pub body_source: String,
479	pub rollback_body_source: Option<String>,
480}
481
482/// Physical node for MIGRATE
483#[derive(Debug, Clone)]
484pub struct MigrateNode {
485	pub target: Option<String>,
486}
487
488/// Physical node for ROLLBACK MIGRATION
489#[derive(Debug, Clone)]
490pub struct RollbackMigrationNode {
491	pub target: Option<String>,
492}
493
494/// Physical node for DISPATCH
495#[derive(Debug, Clone)]
496pub struct DispatchNode {
497	pub namespace: Namespace,
498	pub on_sumtype_id: SumTypeId,
499	pub variant_name: String,
500	pub fields: Vec<(String, Expression)>,
501}
502
503// Create Policy node
504#[derive(Debug, Clone)]
505pub struct CreateColumnPropertyNode {
506	pub namespace: ResolvedNamespace,
507	pub table: Fragment,
508	pub column: Fragment,
509	pub properties: Vec<ColumnPropertyKind>,
510}
511
512#[derive(Debug, Clone)]
513pub enum LetValue {
514	Expression(Expression),
515	Statement(QueryPlan),
516	EmptyFrame,
517}
518
519impl fmt::Display for LetValue {
520	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
521		match self {
522			LetValue::Expression(expr) => write!(f, "{}", expr),
523			LetValue::Statement(query) => write!(f, "Statement({:?})", query),
524			LetValue::EmptyFrame => write!(f, "EmptyFrame"),
525		}
526	}
527}
528
529#[derive(Debug, Clone)]
530pub struct DeclareNode {
531	pub name: Fragment,
532	pub value: LetValue,
533}
534
535#[derive(Debug, Clone)]
536pub enum AssignValue {
537	Expression(Expression),
538	Statement(QueryPlan),
539}
540
541impl fmt::Display for AssignValue {
542	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
543		match self {
544			AssignValue::Expression(expr) => write!(f, "{}", expr),
545			AssignValue::Statement(query) => write!(f, "Statement({:?})", query),
546		}
547	}
548}
549
550#[derive(Debug, Clone)]
551pub struct AssignNode {
552	pub name: Fragment,
553	pub value: AssignValue,
554}
555
556#[derive(Debug, Clone)]
557pub struct VariableNode {
558	pub variable_expr: VariableExpression,
559}
560
561#[derive(Debug, Clone)]
562pub struct EnvironmentNode {}
563
564/// A function parameter in the physical plan
565#[derive(Debug, Clone)]
566pub struct FunctionParameter {
567	/// Parameter name (includes $)
568	pub name: Fragment,
569	/// Optional type constraint
570	pub type_constraint: Option<TypeConstraint>,
571}
572
573#[derive(Debug, Clone)]
574pub struct ScalarizeNode {
575	pub input: Box<QueryPlan>,
576	pub fragment: Fragment,
577}
578
579#[derive(Debug, Clone)]
580pub struct AggregateNode {
581	pub input: Box<QueryPlan>,
582	pub by: Vec<Expression>,
583	pub map: Vec<Expression>,
584}
585
586#[derive(Debug, Clone)]
587pub struct DistinctNode {
588	pub input: Box<QueryPlan>,
589	pub columns: Vec<ResolvedColumn>,
590}
591
592#[derive(Debug, Clone)]
593pub struct AssertNode {
594	pub input: Option<Box<QueryPlan>>,
595	pub conditions: Vec<Expression>,
596	pub message: Option<String>,
597}
598
599#[derive(Debug, Clone)]
600pub struct FilterNode {
601	pub input: Box<QueryPlan>,
602	pub conditions: Vec<Expression>,
603}
604
605#[derive(Debug, Clone)]
606pub struct GateNode {
607	pub input: Box<QueryPlan>,
608	pub conditions: Vec<Expression>,
609}
610
611#[derive(Debug, Clone)]
612pub struct DeleteTableNode {
613	pub input: Option<Box<QueryPlan>>,
614	pub target: Option<ResolvedTable>,
615	pub returning: Option<Vec<Expression>>,
616}
617
618#[derive(Debug, Clone)]
619pub struct InsertTableNode {
620	pub input: Box<QueryPlan>,
621	pub target: ResolvedTable,
622	pub returning: Option<Vec<Expression>>,
623}
624
625#[derive(Debug, Clone)]
626pub struct InsertRingBufferNode {
627	pub input: Box<QueryPlan>,
628	pub target: ResolvedRingBuffer,
629	pub returning: Option<Vec<Expression>>,
630}
631
632#[derive(Debug, Clone)]
633pub struct InsertDictionaryNode {
634	pub input: Box<QueryPlan>,
635	pub target: ResolvedDictionary,
636	pub returning: Option<Vec<Expression>>,
637}
638
639#[derive(Debug, Clone)]
640pub struct UpdateTableNode {
641	pub input: Box<QueryPlan>,
642	pub target: Option<ResolvedTable>,
643	pub returning: Option<Vec<Expression>>,
644}
645
646#[derive(Debug, Clone)]
647pub struct DeleteRingBufferNode {
648	pub input: Option<Box<QueryPlan>>,
649	pub target: ResolvedRingBuffer,
650	pub returning: Option<Vec<Expression>>,
651}
652
653#[derive(Debug, Clone)]
654pub struct UpdateRingBufferNode {
655	pub input: Box<QueryPlan>,
656	pub target: ResolvedRingBuffer,
657	pub returning: Option<Vec<Expression>>,
658}
659
660#[derive(Debug, Clone)]
661pub struct UpdateSeriesNode {
662	pub input: Box<QueryPlan>,
663	pub target: ResolvedSeries,
664	pub returning: Option<Vec<Expression>>,
665}
666
667#[derive(Debug, Clone)]
668pub struct JoinInnerNode {
669	pub left: Box<QueryPlan>,
670	pub right: Box<QueryPlan>,
671	pub on: Vec<Expression>,
672	pub alias: Option<Fragment>,
673}
674
675#[derive(Debug, Clone)]
676pub struct JoinLeftNode {
677	pub left: Box<QueryPlan>,
678	pub right: Box<QueryPlan>,
679	pub on: Vec<Expression>,
680	pub alias: Option<Fragment>,
681}
682
683#[derive(Debug, Clone)]
684pub struct JoinNaturalNode {
685	pub left: Box<QueryPlan>,
686	pub right: Box<QueryPlan>,
687	pub join_type: JoinType,
688	pub alias: Option<Fragment>,
689}
690
691#[derive(Debug, Clone)]
692pub struct AppendQueryNode {
693	pub left: Box<QueryPlan>,
694	pub right: Box<QueryPlan>,
695}
696
697#[derive(Debug, Clone)]
698pub struct SortNode {
699	pub input: Box<QueryPlan>,
700	pub by: Vec<SortKey>,
701}
702
703#[derive(Debug, Clone)]
704pub struct MapNode {
705	pub input: Option<Box<QueryPlan>>,
706	pub map: Vec<Expression>,
707}
708
709#[derive(Debug, Clone)]
710pub struct ExtendNode {
711	pub input: Option<Box<QueryPlan>>,
712	pub extend: Vec<Expression>,
713}
714
715#[derive(Debug, Clone)]
716pub struct PatchNode {
717	pub input: Option<Box<QueryPlan>>,
718	pub assignments: Vec<Expression>,
719}
720
721#[derive(Debug, Clone)]
722pub struct ApplyNode {
723	pub input: Option<Box<QueryPlan>>,
724	pub operator: Fragment, // FIXME becomes OperatorIdentifier
725	pub expressions: Vec<Expression>,
726}
727
728#[derive(Debug, Clone)]
729pub struct InlineDataNode {
730	pub rows: Vec<Vec<AliasExpression>>,
731}
732
733#[derive(Debug, Clone)]
734pub struct IndexScanNode {
735	pub source: ResolvedTable,
736	pub index_name: String,
737}
738
739#[derive(Debug, Clone)]
740pub struct RemoteScanNode {
741	pub address: String,
742	pub token: Option<String>,
743	pub remote_rql: String,
744	pub local_namespace: String,
745	pub remote_name: String,
746	pub variables: Vec<String>,
747}
748
749#[derive(Debug, Clone)]
750pub struct TableScanNode {
751	pub source: ResolvedTable,
752}
753
754#[derive(Debug, Clone)]
755pub struct ViewScanNode {
756	pub source: ResolvedView,
757}
758
759#[derive(Debug, Clone)]
760pub struct RingBufferScanNode {
761	pub source: ResolvedRingBuffer,
762}
763
764#[derive(Debug, Clone)]
765pub struct DictionaryScanNode {
766	pub source: ResolvedDictionary,
767}
768
769#[derive(Debug, Clone)]
770pub struct SeriesScanNode {
771	pub source: ResolvedSeries,
772	pub key_range_start: Option<u64>,
773	pub key_range_end: Option<u64>,
774	pub variant_tag: Option<u8>,
775}
776
777#[derive(Debug, Clone)]
778pub struct InsertSeriesNode {
779	pub input: Box<QueryPlan>,
780	pub target: ResolvedSeries,
781	pub returning: Option<Vec<Expression>>,
782}
783
784#[derive(Debug, Clone)]
785pub struct DeleteSeriesNode {
786	pub input: Option<Box<QueryPlan>>,
787	pub target: ResolvedSeries,
788	pub returning: Option<Vec<Expression>>,
789}
790
791#[derive(Debug, Clone)]
792pub struct GeneratorNode {
793	pub name: Fragment,
794	pub expressions: Vec<Expression>,
795}
796
797#[derive(Debug, Clone)]
798pub struct TableVirtualScanNode {
799	pub source: ResolvedTableVirtual,
800	pub pushdown_context: Option<TableVirtualPushdownContext>,
801}
802
803#[derive(Debug, Clone)]
804pub struct TableVirtualPushdownContext {
805	pub filters: Vec<Expression>,
806	pub projections: Vec<Expression>,
807	pub order_by: Vec<SortKey>,
808	pub limit: Option<usize>,
809}
810
811#[derive(Debug, Clone)]
812pub enum TakeLimit {
813	Literal(usize),
814	Variable(String),
815}
816
817impl fmt::Display for TakeLimit {
818	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
819		match self {
820			TakeLimit::Literal(n) => write!(f, "{}", n),
821			TakeLimit::Variable(name) => write!(f, "${}", name),
822		}
823	}
824}
825
826#[derive(Debug, Clone)]
827pub struct TakeNode {
828	pub input: Box<QueryPlan>,
829	pub take: TakeLimit,
830}
831
832#[derive(Debug, Clone)]
833pub struct WindowNode {
834	pub input: Option<Box<QueryPlan>>,
835	pub kind: WindowKind,
836	pub group_by: Vec<Expression>,
837	pub aggregations: Vec<Expression>,
838	pub ts: Option<String>,
839}
840
841/// O(1) point lookup by row number: `filter rownum == N`
842#[derive(Debug, Clone)]
843pub struct RowPointLookupNode {
844	/// The source to look up in (table, ring buffer, etc.)
845	pub source: ResolvedShape,
846	/// The row number to fetch
847	pub row_number: u64,
848}
849
850/// O(k) list lookup by row numbers: `filter rownum in [a, b, c]`
851#[derive(Debug, Clone)]
852pub struct RowListLookupNode {
853	/// The source to look up in
854	pub source: ResolvedShape,
855	/// The row numbers to fetch
856	pub row_numbers: Vec<u64>,
857}
858
859/// Range scan by row numbers: `filter rownum between X and Y`
860#[derive(Debug, Clone)]
861pub struct RowRangeScanNode {
862	/// The source to scan
863	pub source: ResolvedShape,
864	/// Start of the range (inclusive)
865	pub start: u64,
866	/// End of the range (inclusive)
867	pub end: u64,
868}
869
870/// APPEND statement physical plan node
871#[derive(Debug, Clone)]
872pub enum AppendPhysicalNode {
873	IntoVariable {
874		target: Fragment,
875		source: AppendPhysicalSource,
876	},
877	Query {
878		left: Box<QueryPlan>,
879		right: Box<QueryPlan>,
880	},
881}
882
883/// Source for an APPEND physical plan
884#[derive(Debug, Clone)]
885pub enum AppendPhysicalSource {
886	Statement(Vec<PhysicalPlan>),
887	Inline(InlineDataNode),
888}
889
890#[derive(Debug, Clone)]
891pub struct ConditionalNode {
892	pub condition: Expression,
893	pub then_branch: Box<PhysicalPlan>,
894	pub else_ifs: Vec<ElseIfBranch>,
895	pub else_branch: Option<Box<PhysicalPlan>>,
896}
897
898#[derive(Debug, Clone)]
899pub struct ElseIfBranch {
900	pub condition: Expression,
901	pub then_branch: Box<PhysicalPlan>,
902}
903
904#[derive(Debug, Clone)]
905pub struct LoopPhysicalNode {
906	pub body: Vec<PhysicalPlan>,
907}
908
909#[derive(Debug, Clone)]
910pub struct WhilePhysicalNode {
911	pub condition: Expression,
912	pub body: Vec<PhysicalPlan>,
913}
914
915#[derive(Debug, Clone)]
916pub struct ForPhysicalNode {
917	pub variable_name: Fragment,
918	pub iterable: Box<PhysicalPlan>,
919	pub body: Vec<PhysicalPlan>,
920}
921
922#[derive(Debug, Clone)]
923pub struct DefineFunctionNode {
924	pub name: Fragment,
925	pub parameters: Vec<FunctionParameter>,
926	pub return_type: Option<TypeConstraint>,
927	pub body: Vec<PhysicalPlan>,
928}
929
930#[derive(Debug, Clone)]
931pub struct ReturnNode {
932	pub value: Option<Expression>,
933}
934
935#[derive(Debug, Clone)]
936pub struct CallFunctionNode {
937	pub name: Fragment,
938	pub arguments: Vec<Expression>,
939	pub is_procedure_call: bool,
940}
941
942#[derive(Debug, Clone)]
943pub struct DropNamespaceNode {
944	pub namespace_name: Fragment,
945	pub namespace_id: Option<NamespaceId>,
946	pub if_exists: bool,
947	pub cascade: bool,
948}
949
950#[derive(Debug, Clone)]
951pub struct DropTableNode {
952	pub namespace_name: Fragment,
953	pub table_name: Fragment,
954	pub table_id: Option<TableId>,
955	pub if_exists: bool,
956	pub cascade: bool,
957}
958
959#[derive(Debug, Clone)]
960pub struct DropViewNode {
961	pub namespace_name: Fragment,
962	pub view_name: Fragment,
963	pub view_id: Option<ViewId>,
964	pub if_exists: bool,
965	pub cascade: bool,
966}
967
968#[derive(Debug, Clone)]
969pub struct DropRingBufferNode {
970	pub namespace_name: Fragment,
971	pub ringbuffer_name: Fragment,
972	pub ringbuffer_id: Option<RingBufferId>,
973	pub if_exists: bool,
974	pub cascade: bool,
975}
976
977#[derive(Debug, Clone)]
978pub struct DropDictionaryNode {
979	pub namespace_name: Fragment,
980	pub dictionary_name: Fragment,
981	pub dictionary_id: Option<DictionaryId>,
982	pub if_exists: bool,
983	pub cascade: bool,
984}
985
986#[derive(Debug, Clone)]
987pub struct DropSumTypeNode {
988	pub namespace_name: Fragment,
989	pub sumtype_name: Fragment,
990	pub sumtype_id: Option<SumTypeId>,
991	pub if_exists: bool,
992	pub cascade: bool,
993}
994
995#[derive(Debug, Clone)]
996pub struct DropSubscriptionNode {
997	pub subscription_name: Fragment,
998	pub if_exists: bool,
999	pub cascade: bool,
1000}
1001
1002#[derive(Debug, Clone)]
1003pub struct DropSeriesNode {
1004	pub namespace_name: Fragment,
1005	pub series_name: Fragment,
1006	pub series_id: Option<SeriesId>,
1007	pub if_exists: bool,
1008	pub cascade: bool,
1009}
1010
1011#[derive(Debug, Clone)]
1012pub struct CreateIdentityNode {
1013	pub name: Fragment,
1014}
1015
1016#[derive(Debug, Clone)]
1017pub struct CreateRoleNode {
1018	pub name: Fragment,
1019}
1020
1021#[derive(Debug, Clone)]
1022pub struct GrantNode {
1023	pub role: Fragment,
1024	pub user: Fragment,
1025}
1026
1027#[derive(Debug, Clone)]
1028pub struct RevokeNode {
1029	pub role: Fragment,
1030	pub user: Fragment,
1031}
1032
1033#[derive(Debug, Clone)]
1034pub struct DropIdentityNode {
1035	pub name: Fragment,
1036	pub if_exists: bool,
1037}
1038
1039#[derive(Debug, Clone)]
1040pub struct DropRoleNode {
1041	pub name: Fragment,
1042	pub if_exists: bool,
1043}
1044
1045#[derive(Debug, Clone)]
1046pub struct CreateAuthenticationNode {
1047	pub user: Fragment,
1048	pub method: Fragment,
1049	pub config: collections::HashMap<String, String>,
1050}
1051
1052#[derive(Debug, Clone)]
1053pub struct DropAuthenticationNode {
1054	pub user: Fragment,
1055	pub method: Fragment,
1056	pub if_exists: bool,
1057}
1058
1059#[derive(Debug, Clone)]
1060pub struct CreatePolicyNode {
1061	pub name: Option<Fragment>,
1062	pub target_type: String,
1063	pub scope_namespace: Option<Fragment>,
1064	pub scope_shape: Option<Fragment>,
1065	pub operations: Vec<PolicyOperationNode>,
1066}
1067
1068#[derive(Debug, Clone)]
1069pub struct PolicyOperationNode {
1070	pub operation: String,
1071	pub body_source: String,
1072}
1073
1074#[derive(Debug, Clone)]
1075pub struct AlterPolicyNode {
1076	pub target_type: String,
1077	pub name: Fragment,
1078	pub enable: bool,
1079}
1080
1081#[derive(Debug, Clone)]
1082pub struct DropPolicyNode {
1083	pub target_type: String,
1084	pub name: Fragment,
1085	pub if_exists: bool,
1086}