surrealdb_core/sql/
visit.rs

1use crate::sql::{
2	graph::GraphSubject,
3	order::Ordering,
4	part::{DestructurePart, Recurse, RecurseInstruction},
5	reference::{Reference, ReferenceDeleteStrategy, Refs},
6	statements::{
7		access::{
8			AccessStatementGrant, AccessStatementPurge, AccessStatementRevoke, AccessStatementShow,
9			Subject,
10		},
11		define::{
12			config::{api::ApiConfig, graphql::GraphQLConfig, ConfigInner},
13			ApiAction, DefineConfigStatement,
14		},
15		rebuild::RebuildStatement,
16		AccessStatement, AlterStatement, AlterTableStatement, AnalyzeStatement, CreateStatement,
17		DefineAccessStatement, DefineAnalyzerStatement, DefineApiStatement,
18		DefineDatabaseStatement, DefineEventStatement, DefineFieldStatement,
19		DefineFunctionStatement, DefineIndexStatement, DefineModelStatement,
20		DefineNamespaceStatement, DefineParamStatement, DefineStatement, DefineTableStatement,
21		DefineUserStatement, DeleteStatement, ForeachStatement, IfelseStatement, InfoStatement,
22		InsertStatement, KillStatement, LiveStatement, OptionStatement, OutputStatement,
23		RelateStatement, RemoveAccessStatement, RemoveAnalyzerStatement, RemoveDatabaseStatement,
24		RemoveEventStatement, RemoveFieldStatement, RemoveFunctionStatement, RemoveIndexStatement,
25		RemoveModelStatement, RemoveNamespaceStatement, RemoveParamStatement, RemoveStatement,
26		RemoveTableStatement, RemoveUserStatement, SelectStatement, SetStatement, ShowStatement,
27		SleepStatement, ThrowStatement, UpdateStatement, UpsertStatement, UseStatement,
28	},
29	Array, Block, Cast, Closure, Data, Edges, Entry, Expression, Field, Fields, Function, Future,
30	Geometry, Graph, Id, IdRange, Idiom, Kind, Literal, Mock, Model, Number, Object, Operator,
31	Output, Param, Part, Permission, Permissions, Query, Range, Relation, Statement, Statements,
32	Subquery, TableType, Thing, Value, View,
33};
34use std::ops::Bound;
35
36use super::{
37	access_type::BearerAccess, statements::define::ApiDefinition, AccessType, JwtAccess,
38	RecordAccess,
39};
40
41macro_rules! implement_visitor{
42	($(fn $name:ident($this:ident, $value:ident: &$ty:ty) {
43	    $($t:tt)*
44	})*) => {
45
46		#[allow(dead_code)]
47		pub trait Visit<V: Visitor>{
48			fn visit(&self, v: &mut V) -> Result<(), V::Error>;
49		}
50
51		#[allow(dead_code)]
52		pub trait Visitor: Sized {
53			type Error;
54
55			$(
56				fn $name(&mut self, $value: &$ty) -> Result<(), Self::Error>{
57					$value.visit(self)
58				}
59			)*
60		}
61
62		$(
63			impl<V: Visitor> Visit<V> for $ty {
64				#[allow(unused_variables)]
65				fn visit(&self, $this: &mut V) -> Result<(), V::Error>{
66					let $value = self;
67					$($t)*
68				}
69			}
70		)*
71	};
72}
73
74implement_visitor! {
75	fn visit_statements(this, value: &Statements)  {
76		for v in value.0.iter(){
77			this.visit_statement(v)?;
78		}
79		Ok(())
80	}
81
82	fn visit_statement(this, value: &Statement) {
83		match value {
84			Statement::Value(v) => {
85				this.visit_value(v)?;
86			}
87			Statement::Analyze(a) => {
88				this.visit_analyze_stmt(a)?;
89			}
90			Statement::Begin(_) => {}
91			Statement::Break(_) => {}
92			Statement::Continue(_) => {}
93			Statement::Cancel(_) => {}
94			Statement::Commit(_) => {}
95			Statement::Create(c) => {
96				this.visit_create(c)?;
97			}
98			Statement::Define(d) => {
99				this.visit_define(d)?;
100			}
101			Statement::Delete(d) => {
102				this.visit_delete(d)?;
103			}
104			Statement::Foreach(f) => {
105				this.visit_foreach(f)?;
106			}
107			Statement::Ifelse(i) => {
108				this.visit_if_else(i)?;
109			}
110			Statement::Info(i) => {
111				this.visit_info(i)?;
112			}
113			Statement::Insert(i) => {
114				this.visit_insert(i)?;
115			}
116			Statement::Kill(k) => {
117				this.visit_kill(k)?;
118			}
119			Statement::Live(l) => {
120				this.visit_live(l)?;
121			}
122			Statement::Option(o) => {
123				this.visit_option(o)?;
124			}
125			Statement::Output(o) => {
126				this.visit_output_stmt(o)?;
127			}
128			Statement::Relate(r) => {
129				this.visit_relate(r)?;
130			}
131			Statement::Remove(r) => {
132				this.visit_remove(r)?;
133			}
134			Statement::Select(s) => {
135				this.visit_select(s)?
136			}
137			Statement::Set(s) => {
138				this.visit_set(s)?;
139			}
140			Statement::Show(s) => {
141				this.visit_show(s)?;
142			}
143			Statement::Sleep(s) => {
144				this.visit_sleep(s)?;
145			}
146			Statement::Update(u) => {
147				this.visit_update(u)?;
148			}
149			Statement::Throw(t) => {
150				this.visit_throw(t)?;
151			}
152			Statement::Use(u) => {
153				this.visit_use(u)?;
154			}
155			Statement::Rebuild(r) => {
156				this.visit_rebuild(r)?;
157			}
158			Statement::Upsert(u) => {
159				this.visit_upsert(u)?;
160			}
161			Statement::Alter(a) => {
162				this.visit_alter(a)?;
163			}
164			Statement::Access(a) => {
165				this.visit_access(a)?;
166			},
167		}
168		Ok(())
169	}
170
171	fn visit_access(this, a: &AccessStatement){
172		match a {
173			AccessStatement::Grant(a) => {
174				this.visit_access_grant(a)?;
175			},
176			AccessStatement::Show(a) => {
177				this.visit_access_show(a)?;
178			},
179			AccessStatement::Revoke(a) => {
180				this.visit_access_revoke(a)?;
181			},
182			AccessStatement::Purge(a) => {
183				this.visit_access_purge(a)?;
184			},
185		}
186		Ok(())
187	}
188
189	fn visit_access_grant(this, a: &AccessStatementGrant){
190		this.visit_access_subject(&a.subject)?;
191		Ok(())
192	}
193
194	fn visit_access_subject(this, s: &Subject){
195		match s{
196			Subject::Record(thing) => {
197				this.visit_thing(thing)?;
198			},
199			Subject::User(_) => { }
200		}
201		Ok(())
202	}
203
204	fn visit_access_show(this, a: &AccessStatementShow){
205		if let Some(c) = a.cond.as_ref(){
206			this.visit_value(&c.0)?;
207		}
208		Ok(())
209	}
210	fn visit_access_revoke(this, a: &AccessStatementRevoke){
211		if let Some(c) = a.cond.as_ref(){
212			this.visit_value(&c.0)?;
213		}
214		Ok(())
215	}
216	fn visit_access_purge(this, a: &AccessStatementPurge){
217		Ok(())
218	}
219
220	fn visit_alter(this, a: &AlterStatement){
221		match a {
222			AlterStatement::Table(a) => {
223				this.visit_alter_table(a)?;
224			},
225		}
226		Ok(())
227	}
228
229	fn visit_alter_table(this, a: &AlterTableStatement){
230		if let Some(p) = a.permissions.as_ref(){
231			this.visit_permissions(p)?;
232		}
233		Ok(())
234	}
235
236
237	fn visit_upsert(this, u: &UpsertStatement){
238		for v in u.what.0.iter(){
239			this.visit_value(v)?;
240		}
241		if let Some(d) = u.data.as_ref(){
242			this.visit_data(d)?;
243		}
244		if let Some(o) = u.output.as_ref(){
245			this.visit_output(o)?;
246		}
247		if let Some(c) = u.cond.as_ref(){
248			this.visit_value(&c.0)?;
249		}
250		Ok(())
251
252	}
253
254	fn visit_rebuild(this, r: &RebuildStatement){
255		Ok(())
256	}
257
258	fn visit_use(this, t: &UseStatement){
259		Ok(())
260	}
261
262	fn visit_throw(this, t: &ThrowStatement){
263		this.visit_value(&t.error)
264	}
265
266	fn visit_update(this, u: &UpdateStatement){
267		for v in u.what.0.iter(){
268			this.visit_value(v)?;
269		}
270		if let Some(d) = u.data.as_ref(){
271			this.visit_data(d)?;
272		}
273		if let Some(o) = u.output.as_ref(){
274			this.visit_output(o)?;
275		}
276		if let Some(c) = u.cond.as_ref(){
277			this.visit_value(&c.0)?;
278		}
279		Ok(())
280
281	}
282
283	fn visit_sleep(this, s: &SleepStatement){
284		Ok(())
285	}
286
287	fn visit_show(this, s: &ShowStatement){
288		Ok(())
289	}
290
291	fn visit_set(this, s: &SetStatement){
292		if let Some(k) = s.kind.as_ref(){
293			this.visit_kind(k)?;
294		}
295		this.visit_value(&s.what)?;
296		Ok(())
297	}
298
299	fn visit_select(this, s: &SelectStatement){
300		this.visit_fields(&s.expr)?;
301		if let Some(o) = s.omit.as_ref(){
302			for o in o.0.iter(){
303				this.visit_idiom(o)?;
304			}
305		}
306		for v in s.what.0.iter(){
307			this.visit_value(v)?;
308		}
309		if let Some(c) = s.cond.as_ref(){
310			this.visit_value(&c.0)?;
311		}
312		if let Some(s) = s.split.as_ref(){
313			for s in s.0.iter(){
314				this.visit_idiom(&s.0)?;
315			}
316		}
317		if let Some(g) = s.group.as_ref(){
318			for g in g.0.iter(){
319				this.visit_idiom(&g.0)?;
320			}
321		}
322		if let Some(o) = s.order.as_ref(){
323			this.visit_ordering(o)?;
324		}
325		if let Some(l) = s.limit.as_ref(){
326			this.visit_value(&l.0)?;
327		}
328		if let Some(f) = s.fetch.as_ref(){
329			for f in f.0.iter(){
330				this.visit_value(&f.0)?;
331			}
332		}
333		if let Some(v) = s.version.as_ref(){
334			this.visit_value(&v.0)?;
335		}
336
337		Ok(())
338	}
339
340	fn visit_remove(this, r: &RemoveStatement){
341		match r {
342			RemoveStatement::Namespace(r) => {
343				this.visit_remove_namespace(r)?;
344			},
345			RemoveStatement::Database(r) => {
346				this.visit_remove_database(r)?;
347			},
348			RemoveStatement::Function(r) => {
349				this.visit_remove_function(r)?;
350			},
351			RemoveStatement::Analyzer(r) => {
352				this.visit_remove_analyzer(r)?;
353			},
354			RemoveStatement::Access(r) => {
355				this.visit_remove_access(r)?;
356			},
357			RemoveStatement::Param(r) => {
358				this.visit_remove_param(r)?;
359			},
360			RemoveStatement::Table(r) => {
361				this.visit_remove_table(r)?;
362			},
363			RemoveStatement::Event(r) => {
364				this.visit_remove_event(r)?;
365			},
366			RemoveStatement::Field(r) => {
367				this.visit_remove_field(r)?;
368			},
369			RemoveStatement::Index(r) => {
370				this.visit_remove_index(r)?;
371			},
372			RemoveStatement::User(r) => {
373				this.visit_remove_user(r)?;
374			},
375			RemoveStatement::Model(r) => {
376				this.visit_remove_model(r)?;
377			},
378		}
379		Ok(())
380	}
381
382	fn visit_remove_namespace(this, r: &RemoveNamespaceStatement){
383		Ok(())
384	}
385
386	fn visit_remove_database(this, r: &RemoveDatabaseStatement){
387		Ok(())
388	}
389
390	fn visit_remove_function(this, r: &RemoveFunctionStatement){
391		Ok(())
392	}
393
394	fn visit_remove_analyzer(this, r: &RemoveAnalyzerStatement){
395		Ok(())
396	}
397
398	fn visit_remove_access(this, r: &RemoveAccessStatement){
399		Ok(())
400	}
401
402	fn visit_remove_param(this, r: &RemoveParamStatement){
403		Ok(())
404	}
405
406	fn visit_remove_table(this, r: &RemoveTableStatement){
407		Ok(())
408	}
409
410	fn visit_remove_event(this, r: &RemoveEventStatement){
411		Ok(())
412	}
413
414	fn visit_remove_field(this, r: &RemoveFieldStatement){
415		this.visit_idiom(&r.name)?;
416		Ok(())
417	}
418
419	fn visit_remove_index(this, r: &RemoveIndexStatement){
420		Ok(())
421	}
422
423	fn visit_remove_user(this, r: &RemoveUserStatement){
424		Ok(())
425	}
426
427	fn visit_remove_model(this, r: &RemoveModelStatement){
428		Ok(())
429	}
430
431	fn visit_relate(this, o: &RelateStatement){
432		this.visit_value(&o.kind)?;
433		this.visit_value(&o.from)?;
434		this.visit_value(&o.with)?;
435		if let Some(d) = o.data.as_ref(){
436			this.visit_data(d)?;
437		}
438		if let Some(o) = o.output.as_ref(){
439			this.visit_output(o)?;
440		}
441		Ok(())
442	}
443
444	fn visit_output_stmt(this, o: &OutputStatement){
445		this.visit_value(&o.what)?;
446		if let Some(f) = o.fetch.as_ref(){
447			for f in f.0.iter(){
448				this.visit_value(&f.0)?;
449			}
450		}
451		Ok(())
452	}
453
454	fn visit_option(this, i: &OptionStatement){
455		Ok(())
456	}
457
458	fn visit_live(this, l: &LiveStatement){
459		this.visit_fields(&l.expr)?;
460		this.visit_value(&l.what)?;
461		if let Some(c) = l.cond.as_ref(){
462			this.visit_value(c)?;
463		}
464		if let Some(f) = l.fetch.as_ref(){
465			for f in f.0.iter(){
466				this.visit_value(&f.0)?;
467			}
468		}
469
470		if let Some(s) = l.session.as_ref(){
471			this.visit_value(s)?;
472		}
473		Ok(())
474	}
475
476	fn visit_kill(this, i: &KillStatement){
477		this.visit_value(&i.id)?;
478		Ok(())
479	}
480
481	fn visit_insert(this, i: &InsertStatement){
482		if let Some(v) = i.into.as_ref(){
483			this.visit_value(v)?;
484		}
485		this.visit_data(&i.data)?;
486		if let Some(update) = i.update.as_ref(){
487			this.visit_data(update)?;
488		}
489		if let Some(o) = i.output.as_ref(){
490			this.visit_output(o)?;
491		}
492		Ok(())
493	}
494
495	fn visit_info(this, i: &InfoStatement){
496		Ok(())
497	}
498
499	fn visit_if_else(this, i: &IfelseStatement){
500		for e in i.exprs.iter(){
501			this.visit_value(&e.0)?;
502			this.visit_value(&e.1)?;
503		}
504		if let Some(x) = i.close.as_ref(){
505			this.visit_value(x)?;
506		}
507		Ok(())
508	}
509
510	fn visit_foreach(this, f: &ForeachStatement){
511		this.visit_param(&f.param)?;
512		this.visit_value(&f.range)?;
513		this.visit_block(&f.block)?;
514		Ok(())
515	}
516
517	fn visit_delete(this, d: &DeleteStatement){
518		for v in d.what.iter(){
519			this.visit_value(v)?;
520		}
521		if let Some(c) = d.cond.as_ref(){
522			this.visit_value(&c.0)?;
523		}
524		if let Some(o) = d.output.as_ref(){
525			this.visit_output(o)?;
526		}
527		Ok(())
528	}
529
530	fn visit_define(this, d: &DefineStatement){
531		match d {
532			DefineStatement::Namespace(d) => {
533				this.visit_define_namespace(d)?;
534			},
535			DefineStatement::Database(d) => {
536				this.visit_define_database(d)?;
537			},
538			DefineStatement::Function(d) => {
539				this.visit_define_function(d)?;
540			},
541			DefineStatement::Analyzer(d) => {
542				this.visit_define_analyzer(d)?;
543			},
544			DefineStatement::Param(d) => {
545				this.visit_define_param(d)?;
546			},
547			DefineStatement::Table(d) => {
548				this.visit_define_table(d)?;
549			},
550			DefineStatement::Event(d) => {
551				this.visit_define_event(d)?;
552			},
553			DefineStatement::Field(d) => {
554				this.visit_define_field(d)?;
555			},
556			DefineStatement::Index(d) => {
557				this.visit_define_index(d)?;
558			},
559			DefineStatement::User(d) => {
560				this.visit_define_user(d)?;
561			},
562			DefineStatement::Model(d) => {
563				this.visit_define_model(d)?;
564			},
565			DefineStatement::Access(d) => {
566				this.visit_define_access(d)?;
567			},
568			DefineStatement::Config(d) => {
569				this.visit_define_config(d)?;
570			},
571			DefineStatement::Api(d) => {
572				this.visit_define_api(d)?;
573			},
574		}
575		Ok(())
576	}
577
578	fn visit_define_api(this, d: &DefineApiStatement) {
579		this.visit_value(&d.path)?;
580		for act in d.actions.iter(){
581			this.visit_api_action(act)?;
582		}
583		if let Some(f) = d.fallback.as_ref(){
584			this.visit_value(f)?;
585		}
586		if let Some(config) = d.config.as_ref(){
587			this.visit_api_config(config)?;
588		}
589
590		Ok(())
591	}
592
593	fn visit_api_action(this, a: &ApiAction){
594		this.visit_value(&a.action)?;
595		if let Some(c) = a.config.as_ref(){
596			this.visit_api_config(c)?;
597		}
598		Ok(())
599	}
600
601
602	fn visit_define_config(this, d: &DefineConfigStatement) {
603		this.visit_config_inner(&d.inner)
604	}
605
606	fn visit_config_inner(this, d: &ConfigInner){
607		match d {
608			ConfigInner::GraphQL(graph_qlconfig) => {
609				this.visit_graphql_config(graph_qlconfig)?;
610			},
611			ConfigInner::Api(api_config) => {
612				this.visit_api_config(api_config)?;
613			},
614		}
615		Ok(())
616	}
617
618	fn visit_api_config(this, d: &ApiConfig){
619		if let Some(m) = d.middleware.as_ref(){
620			for m in m.0.iter(){
621				for v in m.1.iter(){
622					this.visit_value(v)?;
623				}
624			}
625		}
626		if let Some(p) = d.permissions.as_ref(){
627			this.visit_permission(p)?;
628		}
629		Ok(())
630	}
631
632	fn visit_graphql_config(this, d: &GraphQLConfig){
633		Ok(())
634	}
635
636
637	fn visit_define_access(this, d: &DefineAccessStatement) {
638		this.visit_access_type(&d.kind)?;
639
640		if let Some(v) = d.authenticate.as_ref(){
641			this.visit_value(v)?;
642		}
643		Ok(())
644	}
645
646	fn visit_access_type(this, a: &AccessType) {
647		match a {
648			AccessType::Record(ac) => this.visit_record_access(ac),
649			AccessType::Jwt(ac) => this.visit_jwt_access(ac),
650			AccessType::Bearer(ac) => this.visit_bearer_access(ac),
651		}
652	}
653
654	fn visit_record_access(this, a: &RecordAccess){
655		if let Some(s) = &a.signup{
656			this.visit_value(s)?;
657		}
658		if let Some(s) = &a.signin{
659			this.visit_value(s)?;
660		}
661		this.visit_jwt_access(&a.jwt)?;
662		if let Some(ac) = &a.bearer{
663			this.visit_bearer_access(ac)?;
664		}
665		Ok(())
666	}
667
668	fn visit_jwt_access(this, a: &JwtAccess){
669		Ok(())
670	}
671
672	fn visit_bearer_access(this, a: &BearerAccess){
673		this.visit_jwt_access(&a.jwt)?;
674		Ok(())
675	}
676
677	fn visit_define_model(this, d: &DefineModelStatement) {
678		this.visit_permission(&d.permissions)?;
679		Ok(())
680	}
681
682	fn visit_define_user(this, d: &DefineUserStatement) {
683		Ok(())
684	}
685
686	fn visit_define_index(this, d: &DefineIndexStatement) {
687		for c in d.cols.0.iter(){
688			this.visit_idiom(c)?;
689		}
690		Ok(())
691	}
692
693	fn visit_define_field(this, d: &DefineFieldStatement) {
694		this.visit_idiom(&d.name)?;
695		if let Some(k) = d.kind.as_ref(){
696			this.visit_kind(k)?;
697		}
698		if let Some(v) = d.value.as_ref(){
699			this.visit_value(v)?;
700		}
701		if let Some(v) = d.assert.as_ref(){
702			this.visit_value(v)?;
703		}
704		if let Some(v) = d.default.as_ref(){
705			this.visit_value(v)?;
706		}
707		this.visit_permissions(&d.permissions)?;
708		if let Some(r) = d.reference.as_ref(){
709			this.visit_reference(r)?;
710		}
711		Ok(())
712	}
713
714	fn visit_reference(this, d: &Reference){
715		this.visit_delete_strategy(&d.on_delete)
716
717	}
718
719	fn visit_delete_strategy(this, d: &ReferenceDeleteStrategy){
720		match d {
721			ReferenceDeleteStrategy::Reject |
722				ReferenceDeleteStrategy::Ignore |
723				ReferenceDeleteStrategy::Cascade |
724				ReferenceDeleteStrategy::Unset => {},
725			ReferenceDeleteStrategy::Custom(value) => {
726				this.visit_value(value)?;
727			},
728
729		}
730		Ok(())
731	}
732
733
734	fn visit_define_event(this, d: &DefineEventStatement){
735		this.visit_value(&d.when)?;
736		for v in d.then.0.iter(){
737			this.visit_value(v)?;
738		}
739		Ok(())
740	}
741
742	fn visit_define_table(this, d: &DefineTableStatement){
743		if let Some(v) = d.view.as_ref(){
744			this.visit_view(v)?;
745		}
746		this.visit_permissions(&d.permissions)?;
747
748		Ok(())
749	}
750
751	fn visit_table_type(this, t: &TableType){
752		match t {
753			TableType::Any |
754				TableType::Normal => {}
755			TableType::Relation(relation) => {
756				this.visit_relation(relation)?;
757			},
758		}
759		Ok(())
760	}
761
762	fn visit_relation(this, r: &Relation){
763		if let Some(k) = r.from.as_ref(){
764			this.visit_kind(k)?;
765		}
766		if let Some(k) = r.to.as_ref(){
767			this.visit_kind(k)?;
768		}
769		Ok(())
770	}
771
772	fn visit_permissions(this, d: &Permissions){
773		this.visit_permission(&d.select)?;
774		this.visit_permission(&d.create)?;
775		this.visit_permission(&d.update)?;
776		this.visit_permission(&d.delete)?;
777		Ok(())
778	}
779
780	fn visit_view(this, v: &View){
781		this.visit_fields(&v.expr)?;
782
783		if let Some(c) = v.cond.as_ref(){
784			this.visit_value(&c.0)?;
785		}
786
787		if let Some(g) = v.group.as_ref(){
788			for g in g.0.iter(){
789				this.visit_idiom(&g.0)?
790			}
791		}
792
793		Ok(())
794	}
795
796	fn visit_define_param(this, d: &DefineParamStatement){
797		this.visit_value(&d.value)?;
798		this.visit_permission(&d.permissions)?;
799		Ok(())
800	}
801
802	fn visit_define_analyzer(this, d: &DefineAnalyzerStatement){
803		Ok(())
804	}
805
806	fn visit_define_function(this, d: &DefineFunctionStatement){
807		for (_, k) in d.args.iter(){
808			this.visit_kind(k)?;
809		}
810		this.visit_block(&d.block)?;
811		this.visit_permission(&d.permissions)?;
812		if let Some(k) = d.returns.as_ref(){
813			this.visit_kind(k)?;
814		}
815		Ok(())
816	}
817
818	fn visit_permission(this, p: &Permission){
819		match p {
820			Permission::None |
821				Permission::Full => {},
822			Permission::Specific(value) => {
823				this.visit_value(value)?;
824			},
825		}
826		Ok(())
827	}
828
829	fn visit_define_database(this,  d: &DefineDatabaseStatement){
830		Ok(())
831	}
832
833	fn visit_define_namespace(this,  d: &DefineNamespaceStatement){
834		Ok(())
835	}
836
837	fn visit_create(this, c: &CreateStatement){
838		for w in c.what.0.iter(){
839			this.visit_value(w)?;
840		}
841
842		if let Some(data) = c.data.as_ref(){
843			this.visit_data(data)?;
844		}
845
846		if let Some(output) = c.output.as_ref(){
847			this.visit_output(output)?;
848		}
849
850		if let Some(v) = c.version.as_ref(){
851			this.visit_value(&v.0)?
852		}
853
854		Ok(())
855	}
856
857	fn visit_output(this, o: &Output){
858		match o {
859			Output::None |
860				Output::Null |
861				Output::Diff |
862				Output::After |
863				Output::Before => {},
864			Output::Fields(fields) => {
865				this.visit_fields(fields)?;
866			},
867		}
868		Ok(())
869	}
870
871	fn visit_data(this, d: &Data){
872		match d {
873			Data::EmptyExpression => {},
874			Data::UpdateExpression(items) |
875				Data::SetExpression(items) => {
876					for (i, op, v) in items{
877						this.visit_idiom(i)?;
878						this.visit_operator(op)?;
879						this.visit_value(v)?;
880					}
881				},
882			Data::UnsetExpression(idioms) => {
883				for i in idioms {
884					this.visit_idiom(i)?;
885				}
886			},
887			Data::PatchExpression(value) |
888				Data::MergeExpression(value) |
889				Data::ReplaceExpression(value) |
890				Data::ContentExpression(value) |
891				Data::SingleExpression(value) => {
892					this.visit_value(value)?;
893				},
894			Data::ValuesExpression(items) => {
895				for (i,v) in items.iter().flat_map(|x| x.iter()){
896					this.visit_idiom(i)?;
897					this.visit_value(v)?;
898				}
899			},
900		}
901		Ok(())
902	}
903
904	fn visit_analyze_stmt(this, v: &AnalyzeStatement){
905		Ok(())
906	}
907
908	fn visit_value(this, value: &Value) {
909		match value {
910
911			Value::None => {}
912			Value::Null => {}
913			Value::Bool(_) => {}
914			Value::Number(x) => {
915				this.visit_number(x)?;
916			}
917			Value::Strand(_) => {}
918			Value::Duration(_) => {}
919			Value::Datetime(_) => {}
920			Value::Uuid(_) => {}
921			Value::Array(x) => {
922				this.visit_array(x)?;
923			}
924			Value::Object(x) => {
925				this.visit_object(x)?;
926			}
927			Value::Geometry(x) => {
928				this.visit_geometry(x)?;
929			}
930			Value::Bytes(x) => {}
931			Value::Thing(x) => {
932				this.visit_thing(x)?;
933			}
934			Value::Param(x) => {
935				this.visit_param(x)?;
936			}
937			Value::Idiom(x) => {
938				this.visit_idiom(x)?;
939			}
940			Value::Table(x) => {}
941			Value::Mock(x) => {
942				this.visit_mock(x)?;
943			}
944			Value::Regex(x) => {}
945			Value::Cast(x) => {
946				this.visit_cast(x)?;
947			}
948			Value::Block(x) => {
949				this.visit_block(x)?;
950			}
951			Value::Range(x) => {
952				this.visit_range(x)?;
953			}
954			Value::Edges(x) => {
955				this.visit_edges(x)?;
956			}
957			Value::Future(x) => {
958				this.visit_future(x)?;
959			}
960			Value::Constant(_) => {}
961			Value::Function(x) => {
962				this.visit_function(x)?;
963			}
964			Value::Subquery(x) => {
965				this.visit_subquery(x)?;
966			}
967			Value::Expression(x) => {
968				this.visit_expression(x)?;
969			}
970			Value::Query(x) => {
971				this.visit_query(x)?;
972			}
973			Value::Model(x) => {
974				this.visit_model(x)?
975			}
976			Value::Closure(x) => {
977				this.visit_closure(x)?;
978			}
979			Value::Refs(x) => {
980				this.visit_refs(x)?;
981			}
982		}
983		Ok(())
984	}
985
986	fn visit_refs(this, r: &Refs){
987		for (_,i) in r.0.iter(){
988			if let Some(i) = i.as_ref(){
989				this.visit_idiom(i)?;
990			}
991		}
992		Ok(())
993	}
994
995
996	fn visit_closure(this, c: &Closure){
997		for (_,ref k) in c.args.iter(){
998			this.visit_kind(k)?;
999		}
1000		if let Some(k) = c.returns.as_ref(){
1001			this.visit_kind(k)?;
1002		}
1003		this.visit_value(&c.body)?;
1004		Ok(())
1005	}
1006
1007	fn visit_model(this, m: &Model) {
1008		for a in m.args.iter(){
1009			this.visit_value(a)?;
1010		}
1011		Ok(())
1012	}
1013
1014	fn visit_query(this, q: &Query){
1015		this.visit_statements(&q.0)
1016
1017	}
1018
1019	fn visit_expression(this, e: &Expression) {
1020		match e {
1021			Expression::Unary { o, v } => {
1022				this.visit_operator(o)?;
1023				this.visit_value(v)?;
1024			},
1025			Expression::Binary { l, o, r } => {
1026				this.visit_value(l)?;
1027				this.visit_operator(o)?;
1028				this.visit_value(r)?;
1029			},
1030		}
1031		Ok(())
1032	}
1033
1034	fn visit_operator(this, o: &Operator){
1035		Ok(())
1036	}
1037
1038	fn visit_subquery(this, s: &Subquery) {
1039		match s {
1040			Subquery::Value(value) => {
1041				this.visit_value(value)?;
1042			},
1043			Subquery::Ifelse(s) => {
1044				this.visit_if_else(s)?;
1045			},
1046			Subquery::Output(s) => {
1047				this.visit_output_stmt(s)?;
1048			},
1049			Subquery::Select(s) => {
1050				this.visit_select(s)?;
1051			},
1052			Subquery::Create(s) => {
1053				this.visit_create(s)?;
1054			},
1055			Subquery::Update(s) => {
1056				this.visit_update(s)?;
1057			},
1058			Subquery::Delete(s) => {
1059				this.visit_delete(s)?;
1060			},
1061			Subquery::Relate(s) => {
1062				this.visit_relate(s)?;
1063			},
1064			Subquery::Insert(s) => {
1065				this.visit_insert(s)?;
1066			},
1067			Subquery::Define(s) => {
1068				this.visit_define(s)?;
1069			},
1070			Subquery::Remove(s) => {
1071				this.visit_remove(s)?;
1072			},
1073			Subquery::Rebuild(s) => {
1074				this.visit_rebuild(s)?;
1075			},
1076			Subquery::Upsert(s) => {
1077				this.visit_upsert(s)?;
1078			},
1079			Subquery::Alter(s) => {
1080				this.visit_alter(s)?;
1081			},
1082		}
1083		Ok(())
1084	}
1085
1086	fn visit_function(this, f: &Function){
1087		match f{
1088			Function::Normal(_, values) |
1089				Function::Custom(_, values) |
1090				Function::Script(_, values) => {
1091					for v in values{
1092						this.visit_value(v)?;
1093					}
1094				}
1095			Function::Anonymous(value, values, _) => {
1096				this.visit_value(value)?;
1097				for v in values{
1098					this.visit_value(v)?;
1099				}
1100			},
1101		}
1102		Ok(())
1103	}
1104
1105	fn visit_future(this,f: &Future){
1106		this.visit_block(&f.0)
1107	}
1108
1109	fn visit_edges(this, e: &Edges){
1110		this.visit_thing(&e.from)?;
1111		for s in e.what.0.iter(){
1112			this.visit_graph_subject(s)?;
1113		}
1114		Ok(())
1115	}
1116
1117	fn visit_range(this, value: &Range){
1118		match value.beg{
1119			Bound::Included(ref x) | Bound::Excluded(ref x) => {
1120				this.visit_value(x)?;
1121			}
1122			Bound::Unbounded => {},
1123		}
1124		match value.end{
1125			Bound::Included(ref x) | Bound::Excluded(ref x) => {
1126				this.visit_value(x)?;
1127			}
1128			Bound::Unbounded => {},
1129		}
1130		Ok(())
1131	}
1132
1133	fn visit_block(this, value: &Block){
1134		for v in value.0.iter(){
1135			this.visit_entry(v)?;
1136		}
1137		Ok(())
1138
1139	}
1140
1141	fn visit_entry(this, entry: &Entry){
1142		match entry{
1143			Entry::Value(value) => {
1144				this.visit_value(value)?;
1145			},
1146			Entry::Set(s) => {
1147				this.visit_set(s)?;
1148			},
1149			Entry::Ifelse(s) => {
1150				this.visit_if_else(s)?;
1151			},
1152			Entry::Select(s) => {
1153				this.visit_select(s)?;
1154			},
1155			Entry::Create(s) => {
1156				this.visit_create(s)?;
1157			},
1158			Entry::Update(s) => {
1159				this.visit_update(s)?;
1160			},
1161			Entry::Delete(s) => {
1162				this.visit_delete(s)?;
1163			},
1164			Entry::Relate(s) => {
1165				this.visit_relate(s)?;
1166			},
1167			Entry::Insert(s) => {
1168				this.visit_insert(s)?;
1169			},
1170			Entry::Output(s) => {
1171				this.visit_output_stmt(s)?;
1172			},
1173			Entry::Define(s) => {
1174				this.visit_define(s)?;
1175			},
1176			Entry::Remove(s) => {
1177				this.visit_remove(s)?;
1178			},
1179			Entry::Throw(s) => {
1180				this.visit_throw(s)?;
1181			},
1182			Entry::Break(_) => {},
1183			Entry::Continue(_) => {},
1184			Entry::Foreach(s) => {
1185				this.visit_foreach(s)?;
1186			},
1187			Entry::Rebuild(s) => {
1188				this.visit_rebuild(s)?;
1189			},
1190			Entry::Upsert(s) => {
1191				this.visit_upsert(s)?;
1192			},
1193			Entry::Alter(s) => {
1194				this.visit_alter(s)?;
1195			},
1196		}
1197		Ok(())
1198	}
1199
1200	fn visit_cast(this, value: &Cast){
1201		this.visit_kind(&value.0)?;
1202		this.visit_value(&value.1)?;
1203		Ok(())
1204	}
1205
1206	fn visit_kind(this, kind: &Kind){
1207		match kind {
1208			Kind::Any |
1209				Kind::Null |
1210				Kind::Bool |
1211				Kind::Bytes |
1212				Kind::Datetime |
1213				Kind::Decimal |
1214				Kind::Duration |
1215				Kind::Float |
1216				Kind::Int |
1217				Kind::Number |
1218				Kind::Object |
1219				Kind::Point |
1220				Kind::String |
1221				Kind::Uuid |
1222				Kind::Regex |
1223				Kind::Range |
1224				Kind::Record(_) |
1225				Kind::Geometry(_) => {}
1226			Kind::Option(kind) => {
1227				this.visit_kind(kind)?;
1228			},
1229			Kind::Either(kinds) => {
1230				for k in kinds.iter() {
1231					this.visit_kind(k)?;
1232				}
1233			},
1234			Kind::Set(kind, _) => {
1235				this.visit_kind(kind)?;
1236			},
1237			Kind::Array(kind, _) => {
1238				this.visit_kind(kind)?;
1239			},
1240			Kind::Function(kinds, kind) => {
1241				if let Some(kinds) = kinds.as_ref(){
1242					for k in kinds.iter() {
1243						this.visit_kind(k)?;
1244					}
1245				}
1246				if let Some(k) = kind {
1247					this.visit_kind(k)?;
1248				}
1249			},
1250			Kind::Literal(literal) => {
1251				this.visit_kind_literal(literal)?;
1252			},
1253			Kind::References(table, idiom) => {
1254				if let Some(idiom) = idiom {
1255					this.visit_idiom(idiom)?;
1256				}
1257			},
1258		}
1259		Ok(())
1260	}
1261
1262	fn visit_kind_literal(this, k: &Literal){
1263		match k{
1264			Literal::String(_) => {},
1265			Literal::Bool(_) => {},
1266			Literal::Duration(_) => {},
1267			Literal::Number(number) => {
1268				this.visit_number(number)?;
1269			},
1270			Literal::Array(kinds) => {
1271				for k in kinds.iter(){
1272					this.visit_kind(k)?;
1273				}
1274			},
1275			Literal::Object(btree_map) => {
1276				for v in btree_map.values(){
1277					this.visit_kind(v)?;
1278				}
1279			},
1280			Literal::DiscriminatedObject(_, btree_maps) => {
1281				for v in btree_maps.iter(){
1282					for v in v.values(){
1283						this.visit_kind(v)?;
1284					}
1285				}
1286			},
1287		}
1288		Ok(())
1289
1290	}
1291
1292	fn visit_mock(_this, _value: &Mock) {
1293		Ok(())
1294	}
1295
1296	fn visit_number(_this, _value: &Number) {
1297		Ok(())
1298	}
1299
1300	fn visit_geometry(_this, _value: &Geometry) {
1301		Ok(())
1302	}
1303
1304	fn visit_array(this, array: &Array) {
1305		for v in array.0.iter(){
1306			this.visit_value(v)?;
1307		}
1308		Ok(())
1309	}
1310
1311	fn visit_object(this, obj: &Object) {
1312		for v in obj.0.values(){
1313			this.visit_value(v)?;
1314		}
1315		Ok(())
1316	}
1317
1318	fn visit_thing(this, t: &Thing) {
1319		this.visit_id(&t.id)
1320	}
1321
1322	fn visit_id(this, id: &Id) {
1323		match id {
1324			Id::Number(_) => {},
1325			Id::String(_) => {},
1326			Id::Uuid(_) => {},
1327			Id::Array(array) => {this.visit_array(array)?;},
1328			Id::Object(object) => {this.visit_object(object)?;},
1329			Id::Generate(_) => {},
1330			Id::Range(id_range) => {
1331				this.visit_id_range(id_range)?;
1332			},
1333		}
1334		Ok(())
1335	}
1336
1337	fn visit_id_range(this, id_range: &IdRange)  {
1338		match id_range.beg{
1339			Bound::Included(ref x) | Bound::Excluded(ref x) => {
1340				this.visit_id(x)?;
1341			},
1342			Bound::Unbounded => {},
1343		}
1344		match id_range.end{
1345			Bound::Included(ref x) | Bound::Excluded(ref x) => {
1346				this.visit_id(x)?;
1347			},
1348			Bound::Unbounded => {},
1349		}
1350		Ok(())
1351	}
1352
1353	fn visit_param(_this, _param: &Param) {
1354		Ok(())
1355	}
1356
1357	fn visit_idiom(this, idiom: &Idiom) {
1358		for p in idiom.0.iter(){
1359			this.visit_part(p)?;
1360		}
1361		Ok(())
1362	}
1363
1364	fn visit_part(this, part: &Part) {
1365		match part{
1366			Part::All |
1367				Part::Flatten |
1368				Part::Last |
1369				Part::First |
1370				Part::Optional |
1371				Part::Field(_) |
1372				Part::Doc |
1373				Part::RepeatRecurse  => {}
1374			Part::Index(number) => {
1375				this.visit_number(number)?;
1376			},
1377			Part::Where(value) | Part::Value(value) | Part::Start(value) => {
1378				this.visit_value(value)?;
1379			},
1380			Part::Graph(graph) => {
1381				this.visit_graph(graph)?;
1382			},
1383			Part::Method(_, values) => {
1384				for v in values {
1385					this.visit_value(v)?;
1386				}
1387			},
1388			Part::Destructure(destructure_parts) => {
1389				for p in destructure_parts.iter(){
1390					this.visit_destructure_part(p)?;
1391				}
1392			},
1393			Part::Recurse(recurse, idiom, recurse_instruction) => {
1394				this.visit_recurse(recurse)?;
1395				if let Some(idiom) = idiom.as_ref(){
1396					this.visit_idiom(idiom)?;
1397				}
1398				if let Some(instr) = recurse_instruction.as_ref(){
1399					this.visit_recurse_instruction(instr)?;
1400				}
1401			},
1402		}
1403		Ok(())
1404	}
1405
1406	fn visit_recurse_instruction(this, r: &RecurseInstruction){
1407		match r {
1408			RecurseInstruction::Path { ..} |
1409				RecurseInstruction::Collect { ..} => {}
1410			RecurseInstruction::Shortest { expects, .. } => {
1411				this.visit_value(expects)?;
1412			},
1413		}
1414		Ok(())
1415	}
1416
1417	fn visit_recurse(_this, _r: &Recurse){
1418		Ok(())
1419	}
1420
1421	fn visit_destructure_part(this, p: &DestructurePart) {
1422		match p {
1423			DestructurePart::All(_) |
1424				DestructurePart::Field(_) => {},
1425				DestructurePart::Aliased(_, idiom) => {
1426					this.visit_idiom(idiom)?;
1427				},
1428				DestructurePart::Destructure(_, destructure_parts) => {
1429					for p in destructure_parts{
1430						this.visit_destructure_part(p)?;
1431					}
1432				},
1433		}
1434		Ok(())
1435	}
1436
1437	fn visit_graph(this, graph: &Graph) {
1438		if let Some(expr) = graph.expr.as_ref(){
1439			this.visit_fields(expr)?;
1440		}
1441
1442		for s in graph.what.0.iter(){
1443			this.visit_graph_subject(s)?;
1444		}
1445
1446		if let Some(c) = graph.cond.as_ref(){
1447			this.visit_value(&c.0)?;
1448		}
1449
1450		if let Some(s) = graph.split.as_ref(){
1451			for s in s.0.iter(){
1452				this.visit_idiom(&s.0)?;
1453			}
1454		}
1455
1456		if let Some(groups) = graph.group.as_ref() {
1457			for g in groups.0.iter(){
1458				this.visit_idiom(&g.0)?;
1459			}
1460		}
1461
1462		if let Some(order) = graph.order.as_ref(){
1463			this.visit_ordering(order)?;
1464		}
1465
1466		if let Some(limit) = graph.limit.as_ref(){
1467			this.visit_value(&limit.0)?;
1468		}
1469
1470		if let Some(start) = graph.start.as_ref(){
1471			this.visit_value(&start.0)?;
1472		}
1473
1474		if let Some(alias) = graph.alias.as_ref(){
1475			this.visit_idiom(alias)?;
1476		}
1477
1478		Ok(())
1479	}
1480
1481
1482	fn visit_ordering(this, ordering: &Ordering){
1483		match ordering{
1484			Ordering::Random => {},
1485			Ordering::Order(order_list) => {
1486				for o in order_list.0.iter(){
1487					this.visit_idiom(&o.value)?;
1488				}
1489			},
1490		}
1491		Ok(())
1492	}
1493
1494	fn visit_fields(this, fields: &Fields) {
1495		for f in fields.0.iter() {
1496			this.visit_field(f)?;
1497		}
1498		Ok(())
1499	}
1500
1501	fn visit_field(this, field: &Field){
1502		match field {
1503			Field::All => {},
1504			Field::Single { expr, alias } => {
1505				this.visit_value(expr)?;
1506				if let Some(alias) = alias.as_ref(){
1507					this.visit_idiom(alias)?;
1508				}
1509			},
1510		}
1511		Ok(())
1512	}
1513
1514	fn visit_graph_subject(this, subject: &GraphSubject){
1515		match subject{
1516			GraphSubject::Table(_) => {},
1517			GraphSubject::Range(_, id_range) => {
1518				this.visit_id_range(id_range)?;
1519			},
1520
1521		}
1522		Ok(())
1523	}
1524
1525	fn visit_api_definition(this, def: &ApiDefinition){
1526		for a in def.actions.iter(){
1527			this.visit_api_action(a)?;
1528		}
1529		if let Some(v) = &def.fallback{
1530			this.visit_value(v)?;
1531		}
1532		if let Some(c) = &def.config{
1533			this.visit_api_config(c)?;
1534		}
1535
1536		Ok(())
1537	}
1538}