squawk_ide/
goto_definition.rs

1use crate::binder;
2use crate::offsets::token_from_offset;
3use crate::resolve;
4use rowan::{TextRange, TextSize};
5use squawk_syntax::{
6    SyntaxKind,
7    ast::{self, AstNode},
8};
9
10pub fn goto_definition(file: ast::SourceFile, offset: TextSize) -> Option<TextRange> {
11    let token = token_from_offset(&file, offset)?;
12    let parent = token.parent()?;
13
14    // goto def on case exprs
15    if (token.kind() == SyntaxKind::WHEN_KW && parent.kind() == SyntaxKind::WHEN_CLAUSE)
16        || (token.kind() == SyntaxKind::ELSE_KW && parent.kind() == SyntaxKind::ELSE_CLAUSE)
17        || (token.kind() == SyntaxKind::END_KW && parent.kind() == SyntaxKind::CASE_EXPR)
18    {
19        for parent in token.parent_ancestors() {
20            if let Some(case_expr) = ast::CaseExpr::cast(parent)
21                && let Some(case_token) = case_expr.case_token()
22            {
23                return Some(case_token.text_range());
24            }
25        }
26    }
27
28    // goto def on COMMIT -> BEGIN/START TRANSACTION
29    if ast::Commit::can_cast(parent.kind()) {
30        if let Some(begin_range) = find_preceding_begin(&file, token.text_range().start()) {
31            return Some(begin_range);
32        }
33    }
34
35    // goto def on ROLLBACK -> BEGIN/START TRANSACTION
36    if ast::Rollback::can_cast(parent.kind()) {
37        if let Some(begin_range) = find_preceding_begin(&file, token.text_range().start()) {
38            return Some(begin_range);
39        }
40    }
41
42    // goto def on BEGIN/START TRANSACTION -> COMMIT or ROLLBACK
43    if ast::Begin::can_cast(parent.kind()) {
44        if let Some(end_range) = find_following_commit_or_rollback(&file, token.text_range().end())
45        {
46            return Some(end_range);
47        }
48    }
49
50    if let Some(name) = ast::Name::cast(parent.clone()) {
51        return Some(name.syntax().text_range());
52    }
53
54    if let Some(name_ref) = ast::NameRef::cast(parent.clone()) {
55        let binder_output = binder::bind(&file);
56        if let Some(ptr) = resolve::resolve_name_ref(&binder_output, &name_ref) {
57            let node = ptr.to_node(file.syntax());
58            return Some(node.text_range());
59        }
60    }
61
62    return None;
63}
64
65fn find_preceding_begin(file: &ast::SourceFile, before: TextSize) -> Option<TextRange> {
66    let mut last_begin: Option<TextRange> = None;
67    for stmt in file.stmts() {
68        if let ast::Stmt::Begin(begin) = stmt {
69            let range = begin.syntax().text_range();
70            if range.end() <= before {
71                last_begin = Some(range);
72            }
73        }
74    }
75    last_begin
76}
77
78fn find_following_commit_or_rollback(file: &ast::SourceFile, after: TextSize) -> Option<TextRange> {
79    for stmt in file.stmts() {
80        let range = match &stmt {
81            ast::Stmt::Commit(commit) => commit.syntax().text_range(),
82            ast::Stmt::Rollback(rollback) => rollback.syntax().text_range(),
83            _ => continue,
84        };
85        if range.start() >= after {
86            return Some(range);
87        }
88    }
89    None
90}
91
92#[cfg(test)]
93mod test {
94    use crate::goto_definition::goto_definition;
95    use crate::test_utils::fixture;
96    use annotate_snippets::{AnnotationKind, Level, Renderer, Snippet, renderer::DecorStyle};
97    use insta::assert_snapshot;
98    use log::info;
99    use squawk_syntax::ast;
100
101    #[track_caller]
102    fn goto(sql: &str) -> String {
103        goto_(sql).expect("should always find a definition")
104    }
105
106    #[track_caller]
107    fn goto_(sql: &str) -> Option<String> {
108        info!("starting");
109        let (mut offset, sql) = fixture(sql);
110        // For go to def we want the previous character since we usually put the
111        // marker after the item we're trying to go to def on.
112        offset = offset.checked_sub(1.into()).unwrap_or_default();
113        let parse = ast::SourceFile::parse(&sql);
114        assert_eq!(parse.errors(), vec![]);
115        let file: ast::SourceFile = parse.tree();
116        if let Some(result) = goto_definition(file, offset) {
117            let offset: usize = offset.into();
118            let group = Level::INFO.primary_title("definition").element(
119                Snippet::source(&sql)
120                    .fold(true)
121                    .annotation(
122                        AnnotationKind::Context
123                            .span(result.into())
124                            .label("2. destination"),
125                    )
126                    .annotation(
127                        AnnotationKind::Context
128                            .span(offset..offset + 1)
129                            .label("1. source"),
130                    ),
131            );
132            let renderer = Renderer::plain().decor_style(DecorStyle::Unicode);
133            return Some(
134                renderer
135                    .render(&[group])
136                    .to_string()
137                    // hacky cleanup to make the text shorter
138                    .replace("info: definition", ""),
139            );
140        }
141        None
142    }
143
144    fn goto_not_found(sql: &str) {
145        assert!(goto_(sql).is_none(), "Should not find a definition");
146    }
147
148    #[test]
149    fn goto_case_when() {
150        assert_snapshot!(goto("
151select case when$0 x > 1 then 1 else 2 end;
152"), @r"
153          ╭▸ 
154        2 │ select case when x > 1 then 1 else 2 end;
155          │        ┬───    ─ 1. source
156          │        │
157          ╰╴       2. destination
158        ");
159    }
160
161    #[test]
162    fn goto_case_else() {
163        assert_snapshot!(goto("
164select case when x > 1 then 1 else$0 2 end;
165"), @r"
166          ╭▸ 
167        2 │ select case when x > 1 then 1 else 2 end;
168          ╰╴       ──── 2. destination       ─ 1. source
169        ");
170    }
171
172    #[test]
173    fn goto_case_end() {
174        assert_snapshot!(goto("
175select case when x > 1 then 1 else 2 end$0;
176"), @r"
177          ╭▸ 
178        2 │ select case when x > 1 then 1 else 2 end;
179          ╰╴       ──── 2. destination             ─ 1. source
180        ");
181    }
182
183    #[test]
184    fn goto_case_end_trailing_semi() {
185        assert_snapshot!(goto("
186select case when x > 1 then 1 else 2 end;$0
187"), @r"
188          ╭▸ 
189        2 │ select case when x > 1 then 1 else 2 end;
190          ╰╴       ──── 2. destination              ─ 1. source
191        ");
192    }
193
194    #[test]
195    fn goto_case_then_not_found() {
196        goto_not_found(
197            "
198select case when x > 1 then$0 1 else 2 end;
199",
200        )
201    }
202
203    #[test]
204    fn rollback_to_begin() {
205        assert_snapshot!(goto(
206            "
207begin;
208select 1;
209rollback$0;
210",
211        ), @r"
212          ╭▸ 
213        2 │ begin;
214          │ ───── 2. destination
215        3 │ select 1;
216        4 │ rollback;
217          ╰╴       ─ 1. source
218        ");
219    }
220
221    #[test]
222    fn goto_drop_table() {
223        assert_snapshot!(goto("
224create table t();
225drop table t$0;
226"), @r"
227          ╭▸ 
228        2 │ create table t();
229          │              ─ 2. destination
230        3 │ drop table t;
231          ╰╴           ─ 1. source
232        ");
233    }
234
235    #[test]
236    fn goto_drop_table_with_schema() {
237        assert_snapshot!(goto("
238create table public.t();
239drop table t$0;
240"), @r"
241          ╭▸ 
242        2 │ create table public.t();
243          │                     ─ 2. destination
244        3 │ drop table t;
245          ╰╴           ─ 1. source
246        ");
247
248        assert_snapshot!(goto("
249create table foo.t();
250drop table foo.t$0;
251"), @r"
252          ╭▸ 
253        2 │ create table foo.t();
254          │                  ─ 2. destination
255        3 │ drop table foo.t;
256          ╰╴               ─ 1. source
257        ");
258
259        goto_not_found(
260            "
261-- defaults to public schema
262create table t();
263drop table foo.t$0;
264",
265        );
266    }
267
268    #[test]
269    fn goto_drop_temp_table() {
270        assert_snapshot!(goto("
271create temp table t();
272drop table t$0;
273"), @r"
274          ╭▸ 
275        2 │ create temp table t();
276          │                   ─ 2. destination
277        3 │ drop table t;
278          ╰╴           ─ 1. source
279        ");
280    }
281
282    #[test]
283    fn goto_drop_temporary_table() {
284        assert_snapshot!(goto("
285create temporary table t();
286drop table t$0;
287"), @r"
288          ╭▸ 
289        2 │ create temporary table t();
290          │                        ─ 2. destination
291        3 │ drop table t;
292          ╰╴           ─ 1. source
293        ");
294    }
295
296    #[test]
297    fn goto_drop_temp_table_with_pg_temp_schema() {
298        assert_snapshot!(goto("
299create temp table t();
300drop table pg_temp.t$0;
301"), @r"
302          ╭▸ 
303        2 │ create temp table t();
304          │                   ─ 2. destination
305        3 │ drop table pg_temp.t;
306          ╰╴                   ─ 1. source
307        ");
308    }
309
310    #[test]
311    fn goto_table_definition_returns_self() {
312        assert_snapshot!(goto("
313create table t$0(x bigint, y bigint);
314"), @r"
315          ╭▸ 
316        2 │ create table t(x bigint, y bigint);
317          │              ┬
318          │              │
319          │              2. destination
320          ╰╴             1. source
321        ");
322    }
323
324    #[test]
325    fn goto_drop_temp_table_shadows_public() {
326        // temp tables shadow public tables when no schema is specified
327        assert_snapshot!(goto("
328create table t();
329create temp table t();
330drop table t$0;
331"), @r"
332          ╭▸ 
333        2 │ create table t();
334          │              ─ 2. destination
335        3 │ create temp table t();
336        4 │ drop table t;
337          ╰╴           ─ 1. source
338        ");
339    }
340
341    #[test]
342    fn goto_drop_public_table_when_temp_exists() {
343        // can still access public table explicitly
344        assert_snapshot!(goto("
345create table t();
346create temp table t();
347drop table public.t$0;
348"), @r"
349          ╭▸ 
350        2 │ create table t();
351          │              ─ 2. destination
352        3 │ create temp table t();
353        4 │ drop table public.t;
354          ╰╴                  ─ 1. source
355        ");
356    }
357
358    #[test]
359    fn goto_drop_table_defined_after() {
360        assert_snapshot!(goto("
361drop table t$0;
362create table t();
363"), @r"
364          ╭▸ 
365        2 │ drop table t;
366          │            ─ 1. source
367        3 │ create table t();
368          ╰╴             ─ 2. destination
369        ");
370    }
371
372    #[test]
373    fn goto_drop_type() {
374        assert_snapshot!(goto("
375create type t as enum ('a', 'b');
376drop type t$0;
377"), @r"
378          ╭▸ 
379        2 │ create type t as enum ('a', 'b');
380          │             ─ 2. destination
381        3 │ drop type t;
382          ╰╴          ─ 1. source
383        ");
384    }
385
386    #[test]
387    fn goto_drop_type_with_schema() {
388        assert_snapshot!(goto("
389create type public.t as enum ('a', 'b');
390drop type t$0;
391"), @r"
392          ╭▸ 
393        2 │ create type public.t as enum ('a', 'b');
394          │                    ─ 2. destination
395        3 │ drop type t;
396          ╰╴          ─ 1. source
397        ");
398
399        assert_snapshot!(goto("
400create type foo.t as enum ('a', 'b');
401drop type foo.t$0;
402"), @r"
403          ╭▸ 
404        2 │ create type foo.t as enum ('a', 'b');
405          │                 ─ 2. destination
406        3 │ drop type foo.t;
407          ╰╴              ─ 1. source
408        ");
409
410        goto_not_found(
411            "
412create type t as enum ('a', 'b');
413drop type foo.t$0;
414",
415        );
416    }
417
418    #[test]
419    fn goto_drop_type_defined_after() {
420        assert_snapshot!(goto("
421drop type t$0;
422create type t as enum ('a', 'b');
423"), @r"
424          ╭▸ 
425        2 │ drop type t;
426          │           ─ 1. source
427        3 │ create type t as enum ('a', 'b');
428          ╰╴            ─ 2. destination
429        ");
430    }
431
432    #[test]
433    fn goto_drop_type_composite() {
434        assert_snapshot!(goto("
435create type person as (name text, age int);
436drop type person$0;
437"), @r"
438          ╭▸ 
439        2 │ create type person as (name text, age int);
440          │             ────── 2. destination
441        3 │ drop type person;
442          ╰╴               ─ 1. source
443        ");
444    }
445
446    #[test]
447    fn goto_drop_type_range() {
448        assert_snapshot!(goto("
449create type int4_range as range (subtype = int4);
450drop type int4_range$0;
451"), @r"
452          ╭▸ 
453        2 │ create type int4_range as range (subtype = int4);
454          │             ────────── 2. destination
455        3 │ drop type int4_range;
456          ╰╴                   ─ 1. source
457        ");
458    }
459
460    #[test]
461    fn goto_cast_operator() {
462        assert_snapshot!(goto("
463create type foo as enum ('a', 'b');
464select x::foo$0;
465"), @r"
466          ╭▸ 
467        2 │ create type foo as enum ('a', 'b');
468          │             ─── 2. destination
469        3 │ select x::foo;
470          ╰╴            ─ 1. source
471        ");
472    }
473
474    #[test]
475    fn goto_cast_function() {
476        assert_snapshot!(goto("
477create type bar as enum ('x', 'y');
478select cast(x as bar$0);
479"), @r"
480          ╭▸ 
481        2 │ create type bar as enum ('x', 'y');
482          │             ─── 2. destination
483        3 │ select cast(x as bar);
484          ╰╴                   ─ 1. source
485        ");
486    }
487
488    #[test]
489    fn goto_cast_with_schema() {
490        assert_snapshot!(goto("
491create type public.baz as enum ('m', 'n');
492select x::public.baz$0;
493"), @r"
494          ╭▸ 
495        2 │ create type public.baz as enum ('m', 'n');
496          │                    ─── 2. destination
497        3 │ select x::public.baz;
498          ╰╴                   ─ 1. source
499        ");
500    }
501
502    #[test]
503    fn begin_to_rollback() {
504        assert_snapshot!(goto(
505            "
506begin$0;
507select 1;
508rollback;
509commit;
510",
511        ), @r"
512          ╭▸ 
513        2 │ begin;
514          │     ─ 1. source
515        3 │ select 1;
516        4 │ rollback;
517          ╰╴──────── 2. destination
518        ");
519    }
520
521    #[test]
522    fn commit_to_begin() {
523        assert_snapshot!(goto(
524            "
525begin;
526select 1;
527commit$0;
528",
529        ), @r"
530          ╭▸ 
531        2 │ begin;
532          │ ───── 2. destination
533        3 │ select 1;
534        4 │ commit;
535          ╰╴     ─ 1. source
536        ");
537    }
538
539    #[test]
540    fn begin_to_commit() {
541        assert_snapshot!(goto(
542            "
543begin$0;
544select 1;
545commit;
546",
547        ), @r"
548          ╭▸ 
549        2 │ begin;
550          │     ─ 1. source
551        3 │ select 1;
552        4 │ commit;
553          ╰╴────── 2. destination
554        ");
555    }
556
557    #[test]
558    fn commit_to_start_transaction() {
559        assert_snapshot!(goto(
560            "
561start transaction;
562select 1;
563commit$0;
564",
565        ), @r"
566          ╭▸ 
567        2 │ start transaction;
568          │ ───────────────── 2. destination
569        3 │ select 1;
570        4 │ commit;
571          ╰╴     ─ 1. source
572        ");
573    }
574
575    #[test]
576    fn start_transaction_to_commit() {
577        assert_snapshot!(goto(
578            "
579start$0 transaction;
580select 1;
581commit;
582",
583        ), @r"
584          ╭▸ 
585        2 │ start transaction;
586          │     ─ 1. source
587        3 │ select 1;
588        4 │ commit;
589          ╰╴────── 2. destination
590        ");
591    }
592
593    #[test]
594    fn goto_with_search_path() {
595        assert_snapshot!(goto(r#"
596set search_path to "foo", public;
597create table foo.t();
598drop table t$0;
599"#), @r"
600          ╭▸ 
601        3 │ create table foo.t();
602          │                  ─ 2. destination
603        4 │ drop table t;
604          ╰╴           ─ 1. source
605        ");
606    }
607
608    #[test]
609    fn goto_with_search_path_and_unspecified_table() {
610        assert_snapshot!(goto(r#"
611set search_path to foo,bar;
612create table t();
613drop table foo.t$0;
614"#), @r"
615          ╭▸ 
616        3 │ create table t();
617          │              ─ 2. destination
618        4 │ drop table foo.t;
619          ╰╴               ─ 1. source
620        ");
621    }
622
623    #[test]
624    fn goto_with_search_path_empty() {
625        goto_not_found(
626            r#"
627set search_path = '';
628create table t();
629drop table t$0;
630"#,
631        );
632    }
633
634    #[test]
635    fn goto_with_search_path_like_variable() {
636        // not actually search path
637        goto_not_found(
638            "
639set bar.search_path to foo, public;
640create table foo.t();
641drop table t$0;
642",
643        )
644    }
645
646    #[test]
647    fn goto_with_search_path_second_schema() {
648        assert_snapshot!(goto("
649set search_path to foo, bar, public;
650create table bar.t();
651drop table t$0;
652"), @r"
653          ╭▸ 
654        3 │ create table bar.t();
655          │                  ─ 2. destination
656        4 │ drop table t;
657          ╰╴           ─ 1. source
658        ");
659    }
660
661    #[test]
662    fn goto_with_search_path_skips_first() {
663        assert_snapshot!(goto("
664set search_path to foo, bar, public;
665create table foo.t();
666create table bar.t();
667drop table t$0;
668"), @r"
669          ╭▸ 
670        3 │ create table foo.t();
671          │                  ─ 2. destination
672        4 │ create table bar.t();
673        5 │ drop table t;
674          ╰╴           ─ 1. source
675        ");
676    }
677
678    #[test]
679    fn goto_without_search_path_uses_default() {
680        assert_snapshot!(goto("
681create table foo.t();
682create table public.t();
683drop table t$0;
684"), @r"
685          ╭▸ 
686        3 │ create table public.t();
687          │                     ─ 2. destination
688        4 │ drop table t;
689          ╰╴           ─ 1. source
690        ");
691    }
692
693    #[test]
694    fn goto_with_set_schema() {
695        assert_snapshot!(goto("
696set schema 'myschema';
697create table myschema.t();
698drop table t$0;
699"), @r"
700          ╭▸ 
701        3 │ create table myschema.t();
702          │                       ─ 2. destination
703        4 │ drop table t;
704          ╰╴           ─ 1. source
705        ");
706    }
707
708    #[test]
709    fn goto_with_set_schema_ignores_other_schemas() {
710        assert_snapshot!(goto("
711set schema 'myschema';
712create table public.t();
713create table myschema.t();
714drop table t$0;
715"), @r"
716          ╭▸ 
717        4 │ create table myschema.t();
718          │                       ─ 2. destination
719        5 │ drop table t;
720          ╰╴           ─ 1. source
721        ");
722    }
723
724    #[test]
725    fn goto_with_search_path_changed_twice() {
726        assert_snapshot!(goto("
727set search_path to foo;
728create table foo.t();
729set search_path to bar;
730create table bar.t();
731drop table t$0;
732"), @r"
733          ╭▸ 
734        5 │ create table bar.t();
735          │                  ─ 2. destination
736        6 │ drop table t;
737          ╰╴           ─ 1. source
738        ");
739
740        assert_snapshot!(goto("
741set search_path to foo;
742create table foo.t();
743drop table t$0;
744set search_path to bar;
745create table bar.t();
746drop table t;
747"), @r"
748          ╭▸ 
749        3 │ create table foo.t();
750          │                  ─ 2. destination
751        4 │ drop table t;
752          ╰╴           ─ 1. source
753        ");
754    }
755
756    #[test]
757    fn goto_with_empty_search_path() {
758        goto_not_found(
759            "
760set search_path to '';
761create table public.t();
762drop table t$0;
763",
764        )
765    }
766
767    #[test]
768    fn goto_with_search_path_uppercase() {
769        assert_snapshot!(goto("
770SET SEARCH_PATH TO foo;
771create table foo.t();
772drop table t$0;
773"), @r"
774          ╭▸ 
775        3 │ create table foo.t();
776          │                  ─ 2. destination
777        4 │ drop table t;
778          ╰╴           ─ 1. source
779        ");
780    }
781
782    #[test]
783    fn goto_table_stmt() {
784        assert_snapshot!(goto("
785create table t();
786table t$0;
787"), @r"
788          ╭▸ 
789        2 │ create table t();
790          │              ─ 2. destination
791        3 │ table t;
792          ╰╴      ─ 1. source
793        ");
794    }
795
796    #[test]
797    fn goto_table_stmt_with_schema() {
798        assert_snapshot!(goto("
799create table public.t();
800table public.t$0;
801"), @r"
802          ╭▸ 
803        2 │ create table public.t();
804          │                     ─ 2. destination
805        3 │ table public.t;
806          ╰╴             ─ 1. source
807        ");
808    }
809
810    #[test]
811    fn goto_table_stmt_with_search_path() {
812        assert_snapshot!(goto("
813set search_path to foo;
814create table foo.t();
815table t$0;
816"), @r"
817          ╭▸ 
818        3 │ create table foo.t();
819          │                  ─ 2. destination
820        4 │ table t;
821          ╰╴      ─ 1. source
822        ");
823    }
824
825    #[test]
826    fn goto_drop_index() {
827        assert_snapshot!(goto("
828create index idx_name on t(x);
829drop index idx_name$0;
830"), @r"
831          ╭▸ 
832        2 │ create index idx_name on t(x);
833          │              ──────── 2. destination
834        3 │ drop index idx_name;
835          ╰╴                  ─ 1. source
836        ");
837    }
838
839    #[test]
840    fn goto_drop_index_with_schema() {
841        assert_snapshot!(goto(r#"
842set search_path to public;
843create index idx_name on t(x);
844drop index public.idx_name$0;
845"#), @r"
846          ╭▸ 
847        3 │ create index idx_name on t(x);
848          │              ──────── 2. destination
849        4 │ drop index public.idx_name;
850          ╰╴                         ─ 1. source
851        ");
852    }
853
854    #[test]
855    fn goto_drop_index_defined_after() {
856        assert_snapshot!(goto("
857drop index idx_name$0;
858create index idx_name on t(x);
859"), @r"
860          ╭▸ 
861        2 │ drop index idx_name;
862          │                   ─ 1. source
863        3 │ create index idx_name on t(x);
864          ╰╴             ──────── 2. destination
865        ");
866    }
867
868    #[test]
869    fn goto_index_definition_returns_self() {
870        assert_snapshot!(goto("
871create index idx_name$0 on t(x);
872"), @r"
873          ╭▸ 
874        2 │ create index idx_name on t(x);
875          │              ┬──────┬
876          │              │      │
877          │              │      1. source
878          ╰╴             2. destination
879        ");
880    }
881
882    #[test]
883    fn goto_drop_index_with_search_path() {
884        assert_snapshot!(goto(r#"
885create index idx_name on t(x);
886set search_path to bar;
887create index idx_name on f(x);
888set search_path to default;
889drop index idx_name$0;
890"#), @r"
891          ╭▸ 
892        2 │ create index idx_name on t(x);
893          │              ──────── 2. destination
894895        6 │ drop index idx_name;
896          ╰╴                  ─ 1. source
897        ");
898    }
899
900    #[test]
901    fn goto_drop_index_multiple() {
902        assert_snapshot!(goto("
903create index idx1 on t(x);
904create index idx2 on t(y);
905drop index idx1, idx2$0;
906"), @r"
907          ╭▸ 
908        3 │ create index idx2 on t(y);
909          │              ──── 2. destination
910        4 │ drop index idx1, idx2;
911          ╰╴                    ─ 1. source
912        ");
913    }
914
915    #[test]
916    fn goto_create_index_table() {
917        assert_snapshot!(goto("
918create table users(id int);
919create index idx_users on users$0(id);
920"), @r"
921          ╭▸ 
922        2 │ create table users(id int);
923          │              ───── 2. destination
924        3 │ create index idx_users on users(id);
925          ╰╴                              ─ 1. source
926        ");
927    }
928
929    #[test]
930    fn goto_create_index_table_with_schema() {
931        assert_snapshot!(goto("
932create table public.users(id int);
933create index idx_users on public.users$0(id);
934"), @r"
935          ╭▸ 
936        2 │ create table public.users(id int);
937          │                     ───── 2. destination
938        3 │ create index idx_users on public.users(id);
939          ╰╴                                     ─ 1. source
940        ");
941    }
942
943    #[test]
944    fn goto_create_index_table_with_search_path() {
945        assert_snapshot!(goto(r#"
946set search_path to foo;
947create table foo.users(id int);
948create index idx_users on users$0(id);
949"#), @r"
950          ╭▸ 
951        3 │ create table foo.users(id int);
952          │                  ───── 2. destination
953        4 │ create index idx_users on users(id);
954          ╰╴                              ─ 1. source
955        ");
956    }
957
958    #[test]
959    fn goto_create_index_temp_table() {
960        assert_snapshot!(goto("
961create temp table users(id int);
962create index idx_users on users$0(id);
963"), @r"
964          ╭▸ 
965        2 │ create temp table users(id int);
966          │                   ───── 2. destination
967        3 │ create index idx_users on users(id);
968          ╰╴                              ─ 1. source
969        ");
970    }
971
972    #[test]
973    fn goto_create_index_column() {
974        assert_snapshot!(goto("
975create table users(id int, email text);
976create index idx_email on users(email$0);
977"), @r"
978          ╭▸ 
979        2 │ create table users(id int, email text);
980          │                            ───── 2. destination
981        3 │ create index idx_email on users(email);
982          ╰╴                                    ─ 1. source
983        ");
984    }
985
986    #[test]
987    fn goto_create_index_first_column() {
988        assert_snapshot!(goto("
989create table users(id int, email text);
990create index idx_id on users(id$0);
991"), @r"
992          ╭▸ 
993        2 │ create table users(id int, email text);
994          │                    ── 2. destination
995        3 │ create index idx_id on users(id);
996          ╰╴                              ─ 1. source
997        ");
998    }
999
1000    #[test]
1001    fn goto_create_index_multiple_columns() {
1002        assert_snapshot!(goto("
1003create table users(id int, email text, name text);
1004create index idx_users on users(id, email$0, name);
1005"), @r"
1006          ╭▸ 
1007        2 │ create table users(id int, email text, name text);
1008          │                            ───── 2. destination
1009        3 │ create index idx_users on users(id, email, name);
1010          ╰╴                                        ─ 1. source
1011        ");
1012    }
1013
1014    #[test]
1015    fn goto_create_index_column_with_schema() {
1016        assert_snapshot!(goto("
1017create table public.users(id int, email text);
1018create index idx_email on public.users(email$0);
1019"), @r"
1020          ╭▸ 
1021        2 │ create table public.users(id int, email text);
1022          │                                   ───── 2. destination
1023        3 │ create index idx_email on public.users(email);
1024          ╰╴                                           ─ 1. source
1025        ");
1026    }
1027
1028    #[test]
1029    fn goto_create_index_column_temp_table() {
1030        assert_snapshot!(goto("
1031create temp table users(id int, email text);
1032create index idx_email on users(email$0);
1033"), @r"
1034          ╭▸ 
1035        2 │ create temp table users(id int, email text);
1036          │                                 ───── 2. destination
1037        3 │ create index idx_email on users(email);
1038          ╰╴                                    ─ 1. source
1039        ");
1040    }
1041
1042    #[test]
1043    fn goto_drop_function() {
1044        assert_snapshot!(goto("
1045create function foo() returns int as $$ select 1 $$ language sql;
1046drop function foo$0();
1047"), @r"
1048          ╭▸ 
1049        2 │ create function foo() returns int as $$ select 1 $$ language sql;
1050          │                 ─── 2. destination
1051        3 │ drop function foo();
1052          ╰╴                ─ 1. source
1053        ");
1054    }
1055
1056    #[test]
1057    fn goto_drop_function_with_schema() {
1058        assert_snapshot!(goto("
1059set search_path to public;
1060create function foo() returns int as $$ select 1 $$ language sql;
1061drop function public.foo$0();
1062"), @r"
1063          ╭▸ 
1064        3 │ create function foo() returns int as $$ select 1 $$ language sql;
1065          │                 ─── 2. destination
1066        4 │ drop function public.foo();
1067          ╰╴                       ─ 1. source
1068        ");
1069    }
1070
1071    #[test]
1072    fn goto_drop_function_defined_after() {
1073        assert_snapshot!(goto("
1074drop function foo$0();
1075create function foo() returns int as $$ select 1 $$ language sql;
1076"), @r"
1077          ╭▸ 
1078        2 │ drop function foo();
1079          │                 ─ 1. source
1080        3 │ create function foo() returns int as $$ select 1 $$ language sql;
1081          ╰╴                ─── 2. destination
1082        ");
1083    }
1084
1085    #[test]
1086    fn goto_function_definition_returns_self() {
1087        assert_snapshot!(goto("
1088create function foo$0() returns int as $$ select 1 $$ language sql;
1089"), @r"
1090          ╭▸ 
1091        2 │ create function foo() returns int as $$ select 1 $$ language sql;
1092          │                 ┬─┬
1093          │                 │ │
1094          │                 │ 1. source
1095          ╰╴                2. destination
1096        ");
1097    }
1098
1099    #[test]
1100    fn goto_drop_function_with_search_path() {
1101        assert_snapshot!(goto("
1102create function foo() returns int as $$ select 1 $$ language sql;
1103set search_path to bar;
1104create function foo() returns int as $$ select 1 $$ language sql;
1105set search_path to default;
1106drop function foo$0();
1107"), @r"
1108          ╭▸ 
1109        2 │ create function foo() returns int as $$ select 1 $$ language sql;
1110          │                 ─── 2. destination
11111112        6 │ drop function foo();
1113          ╰╴                ─ 1. source
1114        ");
1115    }
1116
1117    #[test]
1118    fn goto_drop_function_multiple() {
1119        assert_snapshot!(goto("
1120create function foo() returns int as $$ select 1 $$ language sql;
1121create function bar() returns int as $$ select 1 $$ language sql;
1122drop function foo(), bar$0();
1123"), @r"
1124          ╭▸ 
1125        3 │ create function bar() returns int as $$ select 1 $$ language sql;
1126          │                 ─── 2. destination
1127        4 │ drop function foo(), bar();
1128          ╰╴                       ─ 1. source
1129        ");
1130    }
1131
1132    #[test]
1133    fn goto_drop_function_overloaded() {
1134        assert_snapshot!(goto("
1135create function add(complex) returns complex as $$ select null $$ language sql;
1136create function add(bigint) returns bigint as $$ select 1 $$ language sql;
1137drop function add$0(complex);
1138"), @r"
1139          ╭▸ 
1140        2 │ create function add(complex) returns complex as $$ select null $$ language sql;
1141          │                 ─── 2. destination
1142        3 │ create function add(bigint) returns bigint as $$ select 1 $$ language sql;
1143        4 │ drop function add(complex);
1144          ╰╴                ─ 1. source
1145        ");
1146    }
1147
1148    #[test]
1149    fn goto_drop_function_second_overload() {
1150        assert_snapshot!(goto("
1151create function add(complex) returns complex as $$ select null $$ language sql;
1152create function add(bigint) returns bigint as $$ select 1 $$ language sql;
1153drop function add$0(bigint);
1154"), @r"
1155          ╭▸ 
1156        3 │ create function add(bigint) returns bigint as $$ select 1 $$ language sql;
1157          │                 ─── 2. destination
1158        4 │ drop function add(bigint);
1159          ╰╴                ─ 1. source
1160        ");
1161    }
1162
1163    #[test]
1164    fn goto_select_function_call() {
1165        assert_snapshot!(goto("
1166create function foo() returns int as $$ select 1 $$ language sql;
1167select foo$0();
1168"), @r"
1169          ╭▸ 
1170        2 │ create function foo() returns int as $$ select 1 $$ language sql;
1171          │                 ─── 2. destination
1172        3 │ select foo();
1173          ╰╴         ─ 1. source
1174        ");
1175    }
1176
1177    #[test]
1178    fn goto_select_function_call_with_schema() {
1179        assert_snapshot!(goto("
1180create function public.foo() returns int as $$ select 1 $$ language sql;
1181select public.foo$0();
1182"), @r"
1183          ╭▸ 
1184        2 │ create function public.foo() returns int as $$ select 1 $$ language sql;
1185          │                        ─── 2. destination
1186        3 │ select public.foo();
1187          ╰╴                ─ 1. source
1188        ");
1189    }
1190
1191    #[test]
1192    fn goto_select_function_call_with_search_path() {
1193        assert_snapshot!(goto("
1194set search_path to myschema;
1195create function foo() returns int as $$ select 1 $$ language sql;
1196select myschema.foo$0();
1197"), @r"
1198          ╭▸ 
1199        3 │ create function foo() returns int as $$ select 1 $$ language sql;
1200          │                 ─── 2. destination
1201        4 │ select myschema.foo();
1202          ╰╴                  ─ 1. source
1203        ");
1204    }
1205
1206    #[test]
1207    fn goto_function_call_style_column_access() {
1208        assert_snapshot!(goto("
1209create table t(a int, b int);
1210select a$0(t) from t;
1211"), @r"
1212          ╭▸ 
1213        2 │ create table t(a int, b int);
1214          │                ─ 2. destination
1215        3 │ select a(t) from t;
1216          ╰╴       ─ 1. source
1217        ");
1218    }
1219
1220    #[test]
1221    fn goto_function_call_style_column_access_with_function_precedence() {
1222        assert_snapshot!(goto("
1223create table t(a int, b int);
1224create function b(t) returns int as 'select 1' LANGUAGE sql;
1225select b$0(t) from t;
1226"), @r"
1227          ╭▸ 
1228        3 │ create function b(t) returns int as 'select 1' LANGUAGE sql;
1229          │                 ─ 2. destination
1230        4 │ select b(t) from t;
1231          ╰╴       ─ 1. source
1232        ");
1233    }
1234
1235    #[test]
1236    fn goto_function_call_style_column_access_table_arg() {
1237        assert_snapshot!(goto("
1238create table t(a int, b int);
1239select a(t$0) from t;
1240"), @r"
1241          ╭▸ 
1242        2 │ create table t(a int, b int);
1243          │              ─ 2. destination
1244        3 │ select a(t) from t;
1245          ╰╴         ─ 1. source
1246        ");
1247    }
1248
1249    #[test]
1250    fn goto_function_call_style_column_access_table_arg_with_function() {
1251        assert_snapshot!(goto("
1252create table t(a int, b int);
1253create function b(t) returns int as 'select 1' LANGUAGE sql;
1254select b(t$0) from t;
1255"), @r"
1256          ╭▸ 
1257        2 │ create table t(a int, b int);
1258          │              ─ 2. destination
1259        3 │ create function b(t) returns int as 'select 1' LANGUAGE sql;
1260        4 │ select b(t) from t;
1261          ╰╴         ─ 1. source
1262        ");
1263    }
1264
1265    #[test]
1266    fn goto_function_call_multiple_args_not_column_access() {
1267        goto_not_found(
1268            "
1269create table t(a int, b int);
1270select a$0(t, 1) from t;
1271",
1272        );
1273    }
1274
1275    #[test]
1276    fn goto_field_style_function_call() {
1277        assert_snapshot!(goto("
1278create table t(a int);
1279create function b(t) returns int as 'select 1' language sql;
1280select t.b$0 from t;
1281"), @r"
1282          ╭▸ 
1283        3 │ create function b(t) returns int as 'select 1' language sql;
1284          │                 ─ 2. destination
1285        4 │ select t.b from t;
1286          ╰╴         ─ 1. source
1287        ");
1288    }
1289
1290    #[test]
1291    fn goto_field_style_function_call_column_precedence() {
1292        assert_snapshot!(goto("
1293create table t(a int, b int);
1294create function b(t) returns int as 'select 1' language sql;
1295select t.b$0 from t;
1296"), @r"
1297          ╭▸ 
1298        2 │ create table t(a int, b int);
1299          │                       ─ 2. destination
1300        3 │ create function b(t) returns int as 'select 1' language sql;
1301        4 │ select t.b from t;
1302          ╰╴         ─ 1. source
1303        ");
1304    }
1305
1306    #[test]
1307    fn goto_field_style_function_call_table_ref() {
1308        assert_snapshot!(goto("
1309create table t(a int);
1310create function b(t) returns int as 'select 1' language sql;
1311select t$0.b from t;
1312"), @r"
1313          ╭▸ 
1314        2 │ create table t(a int);
1315          │              ─ 2. destination
1316        3 │ create function b(t) returns int as 'select 1' language sql;
1317        4 │ select t.b from t;
1318          ╰╴       ─ 1. source
1319        ");
1320    }
1321
1322    #[test]
1323    fn goto_function_call_style_in_where() {
1324        assert_snapshot!(goto("
1325create table t(a int, b int);
1326select * from t where a$0(t) > 0;
1327"), @r"
1328          ╭▸ 
1329        2 │ create table t(a int, b int);
1330          │                ─ 2. destination
1331        3 │ select * from t where a(t) > 0;
1332          ╰╴                      ─ 1. source
1333        ");
1334    }
1335
1336    #[test]
1337    fn goto_function_call_style_in_where_function_precedence() {
1338        assert_snapshot!(goto("
1339create table t(a int, b int);
1340create function b(t) returns int as 'select 1' language sql;
1341select * from t where b$0(t) > 0;
1342"), @r"
1343          ╭▸ 
1344        3 │ create function b(t) returns int as 'select 1' language sql;
1345          │                 ─ 2. destination
1346        4 │ select * from t where b(t) > 0;
1347          ╰╴                      ─ 1. source
1348        ");
1349    }
1350
1351    #[test]
1352    fn goto_field_style_function_call_in_where() {
1353        assert_snapshot!(goto("
1354create table t(a int);
1355create function b(t) returns int as 'select 1' language sql;
1356select * from t where t.b$0 > 0;
1357"), @r"
1358          ╭▸ 
1359        3 │ create function b(t) returns int as 'select 1' language sql;
1360          │                 ─ 2. destination
1361        4 │ select * from t where t.b > 0;
1362          ╰╴                        ─ 1. source
1363        ");
1364    }
1365
1366    #[test]
1367    fn goto_field_style_in_where_column_precedence() {
1368        assert_snapshot!(goto("
1369create table t(a int, b int);
1370create function b(t) returns int as 'select 1' language sql;
1371select * from t where t.b$0 > 0;
1372"), @r"
1373          ╭▸ 
1374        2 │ create table t(a int, b int);
1375          │                       ─ 2. destination
1376        3 │ create function b(t) returns int as 'select 1' language sql;
1377        4 │ select * from t where t.b > 0;
1378          ╰╴                        ─ 1. source
1379        ");
1380    }
1381
1382    #[test]
1383    fn goto_function_call_style_table_arg_in_where() {
1384        assert_snapshot!(goto("
1385create table t(a int);
1386select * from t where a(t$0) > 2;
1387"), @r"
1388          ╭▸ 
1389        2 │ create table t(a int);
1390          │              ─ 2. destination
1391        3 │ select * from t where a(t) > 2;
1392          ╰╴                        ─ 1. source
1393        ");
1394    }
1395
1396    #[test]
1397    fn goto_qualified_table_ref_in_where() {
1398        assert_snapshot!(goto("
1399create table t(a int);
1400create function b(t) returns int as 'select 1' language sql;
1401select * from t where t$0.b > 2;
1402"), @r"
1403          ╭▸ 
1404        2 │ create table t(a int);
1405          │              ─ 2. destination
1406        3 │ create function b(t) returns int as 'select 1' language sql;
1407        4 │ select * from t where t.b > 2;
1408          ╰╴                      ─ 1. source
1409        ");
1410    }
1411
1412    #[test]
1413    fn goto_function_call_style_in_order_by() {
1414        assert_snapshot!(goto("
1415create table t(a int, b int);
1416create function b(t) returns int as 'select 1' language sql;
1417select * from t order by b$0(t);
1418"), @r"
1419          ╭▸ 
1420        3 │ create function b(t) returns int as 'select 1' language sql;
1421          │                 ─ 2. destination
1422        4 │ select * from t order by b(t);
1423          ╰╴                         ─ 1. source
1424        ");
1425    }
1426
1427    #[test]
1428    fn goto_field_style_in_order_by() {
1429        assert_snapshot!(goto("
1430create table t(a int);
1431create function b(t) returns int as 'select 1' language sql;
1432select * from t order by t.b$0;
1433"), @r"
1434          ╭▸ 
1435        3 │ create function b(t) returns int as 'select 1' language sql;
1436          │                 ─ 2. destination
1437        4 │ select * from t order by t.b;
1438          ╰╴                           ─ 1. source
1439        ");
1440    }
1441
1442    #[test]
1443    fn goto_function_call_style_in_group_by() {
1444        assert_snapshot!(goto("
1445create table t(a int, b int);
1446select * from t group by a$0(t);
1447"), @r"
1448          ╭▸ 
1449        2 │ create table t(a int, b int);
1450          │                ─ 2. destination
1451        3 │ select * from t group by a(t);
1452          ╰╴                         ─ 1. source
1453        ");
1454    }
1455
1456    #[test]
1457    fn goto_field_style_in_group_by() {
1458        assert_snapshot!(goto("
1459create table t(a int);
1460create function b(t) returns int as 'select 1' language sql;
1461select * from t group by t.b$0;
1462"), @r"
1463          ╭▸ 
1464        3 │ create function b(t) returns int as 'select 1' language sql;
1465          │                 ─ 2. destination
1466        4 │ select * from t group by t.b;
1467          ╰╴                           ─ 1. source
1468        ");
1469    }
1470
1471    #[test]
1472    fn goto_cte_table() {
1473        assert_snapshot!(goto("
1474with x as (select 1 as a)
1475select a from x$0;
1476"), @r"
1477          ╭▸ 
1478        2 │ with x as (select 1 as a)
1479          │      ─ 2. destination
1480        3 │ select a from x;
1481          ╰╴              ─ 1. source
1482        ");
1483    }
1484
1485    #[test]
1486    fn goto_cte_column() {
1487        assert_snapshot!(goto("
1488with x as (select 1 as a)
1489select a$0 from x;
1490"), @r"
1491          ╭▸ 
1492        2 │ with x as (select 1 as a)
1493          │                        ─ 2. destination
1494        3 │ select a from x;
1495          ╰╴       ─ 1. source
1496        ");
1497    }
1498
1499    #[test]
1500    fn goto_cte_multiple_columns() {
1501        assert_snapshot!(goto("
1502with x as (select 1 as a, 2 as b)
1503select b$0 from x;
1504"), @r"
1505          ╭▸ 
1506        2 │ with x as (select 1 as a, 2 as b)
1507          │                                ─ 2. destination
1508        3 │ select b from x;
1509          ╰╴       ─ 1. source
1510        ");
1511    }
1512
1513    #[test]
1514    fn goto_cte_nested() {
1515        assert_snapshot!(goto("
1516with x as (select 1 as a),
1517     y as (select a from x)
1518select a$0 from y;
1519"), @r"
1520          ╭▸ 
1521        3 │      y as (select a from x)
1522          │                   ─ 2. destination
1523        4 │ select a from y;
1524          ╰╴       ─ 1. source
1525        ");
1526    }
1527
1528    #[test]
1529    fn goto_cte_unnamed_column() {
1530        assert_snapshot!(goto(r#"
1531with x as (select 1)
1532select "?column?"$0 from x;
1533"#), @r#"
1534          ╭▸ 
1535        2 │ with x as (select 1)
1536          │                   ─ 2. destination
1537        3 │ select "?column?" from x;
1538          ╰╴                ─ 1. source
1539        "#);
1540    }
1541
1542    #[test]
1543    fn goto_cte_star_expansion() {
1544        assert_snapshot!(goto("
1545with t as (select 1 a),
1546     y as (select * from t)
1547select a$0 from y;
1548"), @r"
1549          ╭▸ 
1550        2 │ with t as (select 1 a),
1551          │                     ─ 2. destination
1552        3 │      y as (select * from t)
1553        4 │ select a from y;
1554          ╰╴       ─ 1. source
1555        ");
1556    }
1557
1558    #[test]
1559    fn goto_cte_reference_inside_cte() {
1560        assert_snapshot!(goto("
1561with t as (select 1 a),
1562     y as (select a$0 from t)
1563select a from y;
1564"), @r"
1565          ╭▸ 
1566        2 │ with t as (select 1 a),
1567          │                     ─ 2. destination
1568        3 │      y as (select a from t)
1569          ╰╴                  ─ 1. source
1570        ");
1571    }
1572
1573    #[test]
1574    fn goto_cte_with_column_list() {
1575        assert_snapshot!(goto("
1576with t(a) as (select 1)
1577select a$0 from t;
1578"), @r"
1579          ╭▸ 
1580        2 │ with t(a) as (select 1)
1581          │        ─ 2. destination
1582        3 │ select a from t;
1583          ╰╴       ─ 1. source
1584        ");
1585    }
1586
1587    #[test]
1588    fn goto_cte_with_partial_column_list() {
1589        assert_snapshot!(goto("
1590with t(x) as (select 1 as a, 2 as b)
1591select b$0 from t;
1592"), @r"
1593          ╭▸ 
1594        2 │ with t(x) as (select 1 as a, 2 as b)
1595          │                                   ─ 2. destination
1596        3 │ select b from t;
1597          ╰╴       ─ 1. source
1598        ");
1599    }
1600
1601    #[test]
1602    fn goto_cte_with_partial_column_list_renamed() {
1603        assert_snapshot!(goto("
1604with t(x) as (select 1 as a, 2 as b)
1605select x$0 from t;
1606"), @r"
1607          ╭▸ 
1608        2 │ with t(x) as (select 1 as a, 2 as b)
1609          │        ─ 2. destination
1610        3 │ select x from t;
1611          ╰╴       ─ 1. source
1612        ");
1613    }
1614
1615    #[test]
1616    fn goto_cte_column_list_overwrites_column() {
1617        goto_not_found(
1618            "
1619with t(x) as (select 1 as a)
1620select a$0 from t;
1621",
1622        );
1623    }
1624
1625    #[test]
1626    fn goto_cte_shadows_table() {
1627        assert_snapshot!(goto("
1628create table t(a int);
1629with t as (select a$0 from t)
1630select a from t;
1631"), @r"
1632          ╭▸ 
1633        2 │ create table t(a int);
1634          │                ─ 2. destination
1635        3 │ with t as (select a from t)
1636          ╰╴                  ─ 1. source
1637        ");
1638    }
1639
1640    #[test]
1641    fn goto_subquery_column() {
1642        assert_snapshot!(goto("
1643select a$0 from (select 1 a);
1644"), @r"
1645          ╭▸ 
1646        2 │ select a from (select 1 a);
1647          ╰╴       ─ 1. source      ─ 2. destination
1648        ");
1649    }
1650
1651    #[test]
1652    fn goto_subquery_column_with_as() {
1653        assert_snapshot!(goto("
1654select a$0 from (select 1 as a);
1655"), @r"
1656          ╭▸ 
1657        2 │ select a from (select 1 as a);
1658          ╰╴       ─ 1. source         ─ 2. destination
1659        ");
1660    }
1661
1662    #[test]
1663    fn goto_subquery_column_multiple_columns() {
1664        assert_snapshot!(goto("
1665select b$0 from (select 1 a, 2 b);
1666"), @r"
1667          ╭▸ 
1668        2 │ select b from (select 1 a, 2 b);
1669          ╰╴       ─ 1. source           ─ 2. destination
1670        ");
1671    }
1672
1673    #[test]
1674    fn goto_subquery_column_nested_parens() {
1675        assert_snapshot!(goto("
1676select a$0 from ((select 1 a));
1677"), @r"
1678          ╭▸ 
1679        2 │ select a from ((select 1 a));
1680          ╰╴       ─ 1. source       ─ 2. destination
1681        ");
1682    }
1683
1684    #[test]
1685    fn goto_insert_table() {
1686        assert_snapshot!(goto("
1687create table users(id int, email text);
1688insert into users$0(id, email) values (1, 'test@example.com');
1689"), @r"
1690          ╭▸ 
1691        2 │ create table users(id int, email text);
1692          │              ───── 2. destination
1693        3 │ insert into users(id, email) values (1, 'test@example.com');
1694          ╰╴                ─ 1. source
1695        ");
1696    }
1697
1698    #[test]
1699    fn goto_insert_table_with_schema() {
1700        assert_snapshot!(goto("
1701create table public.users(id int, email text);
1702insert into public.users$0(id, email) values (1, 'test@example.com');
1703"), @r"
1704          ╭▸ 
1705        2 │ create table public.users(id int, email text);
1706          │                     ───── 2. destination
1707        3 │ insert into public.users(id, email) values (1, 'test@example.com');
1708          ╰╴                       ─ 1. source
1709        ");
1710    }
1711
1712    #[test]
1713    fn goto_insert_column() {
1714        assert_snapshot!(goto("
1715create table users(id int, email text);
1716insert into users(id$0, email) values (1, 'test@example.com');
1717"), @r"
1718          ╭▸ 
1719        2 │ create table users(id int, email text);
1720          │                    ── 2. destination
1721        3 │ insert into users(id, email) values (1, 'test@example.com');
1722          ╰╴                   ─ 1. source
1723        ");
1724    }
1725
1726    #[test]
1727    fn goto_insert_column_second() {
1728        assert_snapshot!(goto("
1729create table users(id int, email text);
1730insert into users(id, email$0) values (1, 'test@example.com');
1731"), @r"
1732          ╭▸ 
1733        2 │ create table users(id int, email text);
1734          │                            ───── 2. destination
1735        3 │ insert into users(id, email) values (1, 'test@example.com');
1736          ╰╴                          ─ 1. source
1737        ");
1738    }
1739
1740    #[test]
1741    fn goto_insert_column_with_schema() {
1742        assert_snapshot!(goto("
1743create table public.users(id int, email text);
1744insert into public.users(email$0) values ('test@example.com');
1745"), @r"
1746          ╭▸ 
1747        2 │ create table public.users(id int, email text);
1748          │                                   ───── 2. destination
1749        3 │ insert into public.users(email) values ('test@example.com');
1750          ╰╴                             ─ 1. source
1751        ");
1752    }
1753
1754    #[test]
1755    fn goto_insert_table_with_search_path() {
1756        assert_snapshot!(goto("
1757set search_path to foo;
1758create table foo.users(id int, email text);
1759insert into users$0(id, email) values (1, 'test@example.com');
1760"), @r"
1761          ╭▸ 
1762        3 │ create table foo.users(id int, email text);
1763          │                  ───── 2. destination
1764        4 │ insert into users(id, email) values (1, 'test@example.com');
1765          ╰╴                ─ 1. source
1766        ");
1767    }
1768
1769    #[test]
1770    fn goto_insert_column_with_search_path() {
1771        assert_snapshot!(goto("
1772set search_path to myschema;
1773create table myschema.users(id int, email text, name text);
1774insert into users(email$0, name) values ('test@example.com', 'Test');
1775"), @r"
1776          ╭▸ 
1777        3 │ create table myschema.users(id int, email text, name text);
1778          │                                     ───── 2. destination
1779        4 │ insert into users(email, name) values ('test@example.com', 'Test');
1780          ╰╴                      ─ 1. source
1781        ");
1782    }
1783
1784    #[test]
1785    fn goto_delete_table() {
1786        assert_snapshot!(goto("
1787create table users(id int, email text);
1788delete from users$0 where id = 1;
1789"), @r"
1790          ╭▸ 
1791        2 │ create table users(id int, email text);
1792          │              ───── 2. destination
1793        3 │ delete from users where id = 1;
1794          ╰╴                ─ 1. source
1795        ");
1796    }
1797
1798    #[test]
1799    fn goto_delete_table_with_schema() {
1800        assert_snapshot!(goto("
1801create table public.users(id int, email text);
1802delete from public.users$0 where id = 1;
1803"), @r"
1804          ╭▸ 
1805        2 │ create table public.users(id int, email text);
1806          │                     ───── 2. destination
1807        3 │ delete from public.users where id = 1;
1808          ╰╴                       ─ 1. source
1809        ");
1810    }
1811
1812    #[test]
1813    fn goto_delete_table_with_search_path() {
1814        assert_snapshot!(goto("
1815set search_path to foo;
1816create table foo.users(id int, email text);
1817delete from users$0 where id = 1;
1818"), @r"
1819          ╭▸ 
1820        3 │ create table foo.users(id int, email text);
1821          │                  ───── 2. destination
1822        4 │ delete from users where id = 1;
1823          ╰╴                ─ 1. source
1824        ");
1825    }
1826
1827    #[test]
1828    fn goto_delete_temp_table() {
1829        assert_snapshot!(goto("
1830create temp table users(id int, email text);
1831delete from users$0 where id = 1;
1832"), @r"
1833          ╭▸ 
1834        2 │ create temp table users(id int, email text);
1835          │                   ───── 2. destination
1836        3 │ delete from users where id = 1;
1837          ╰╴                ─ 1. source
1838        ");
1839    }
1840
1841    #[test]
1842    fn goto_delete_where_column() {
1843        assert_snapshot!(goto("
1844create table users(id int, email text);
1845delete from users where id$0 = 1;
1846"), @r"
1847          ╭▸ 
1848        2 │ create table users(id int, email text);
1849          │                    ── 2. destination
1850        3 │ delete from users where id = 1;
1851          ╰╴                         ─ 1. source
1852        ");
1853    }
1854
1855    #[test]
1856    fn goto_delete_where_column_second() {
1857        assert_snapshot!(goto("
1858create table users(id int, email text);
1859delete from users where email$0 = 'test@example.com';
1860"), @r"
1861          ╭▸ 
1862        2 │ create table users(id int, email text);
1863          │                            ───── 2. destination
1864        3 │ delete from users where email = 'test@example.com';
1865          ╰╴                            ─ 1. source
1866        ");
1867    }
1868
1869    #[test]
1870    fn goto_delete_where_column_with_schema() {
1871        assert_snapshot!(goto("
1872create table public.users(id int, email text, name text);
1873delete from public.users where name$0 = 'Test';
1874"), @r"
1875          ╭▸ 
1876        2 │ create table public.users(id int, email text, name text);
1877          │                                               ──── 2. destination
1878        3 │ delete from public.users where name = 'Test';
1879          ╰╴                                  ─ 1. source
1880        ");
1881    }
1882
1883    #[test]
1884    fn goto_delete_where_column_with_search_path() {
1885        assert_snapshot!(goto("
1886set search_path to myschema;
1887create table myschema.users(id int, email text, active boolean);
1888delete from users where active$0 = true;
1889"), @r"
1890          ╭▸ 
1891        3 │ create table myschema.users(id int, email text, active boolean);
1892          │                                                 ────── 2. destination
1893        4 │ delete from users where active = true;
1894          ╰╴                             ─ 1. source
1895        ");
1896    }
1897
1898    #[test]
1899    fn goto_delete_where_multiple_columns() {
1900        assert_snapshot!(goto("
1901create table users(id int, email text, active boolean);
1902delete from users where id$0 = 1 and active = true;
1903"), @r"
1904          ╭▸ 
1905        2 │ create table users(id int, email text, active boolean);
1906          │                    ── 2. destination
1907        3 │ delete from users where id = 1 and active = true;
1908          ╰╴                         ─ 1. source
1909        ");
1910    }
1911
1912    #[test]
1913    fn goto_select_from_table() {
1914        assert_snapshot!(goto("
1915create table users(id int, email text);
1916select * from users$0;
1917"), @r"
1918          ╭▸ 
1919        2 │ create table users(id int, email text);
1920          │              ───── 2. destination
1921        3 │ select * from users;
1922          ╰╴                  ─ 1. source
1923        ");
1924    }
1925
1926    #[test]
1927    fn goto_select_from_table_with_schema() {
1928        assert_snapshot!(goto("
1929create table public.users(id int, email text);
1930select * from public.users$0;
1931"), @r"
1932          ╭▸ 
1933        2 │ create table public.users(id int, email text);
1934          │                     ───── 2. destination
1935        3 │ select * from public.users;
1936          ╰╴                         ─ 1. source
1937        ");
1938    }
1939
1940    #[test]
1941    fn goto_select_from_table_with_search_path() {
1942        assert_snapshot!(goto("
1943set search_path to foo;
1944create table foo.users(id int, email text);
1945select * from users$0;
1946"), @r"
1947          ╭▸ 
1948        3 │ create table foo.users(id int, email text);
1949          │                  ───── 2. destination
1950        4 │ select * from users;
1951          ╰╴                  ─ 1. source
1952        ");
1953    }
1954
1955    #[test]
1956    fn goto_select_from_temp_table() {
1957        assert_snapshot!(goto("
1958create temp table users(id int, email text);
1959select * from users$0;
1960"), @r"
1961          ╭▸ 
1962        2 │ create temp table users(id int, email text);
1963          │                   ───── 2. destination
1964        3 │ select * from users;
1965          ╰╴                  ─ 1. source
1966        ");
1967    }
1968
1969    #[test]
1970    fn goto_select_from_table_defined_after() {
1971        assert_snapshot!(goto("
1972select * from users$0;
1973create table users(id int, email text);
1974"), @r"
1975          ╭▸ 
1976        2 │ select * from users;
1977          │                   ─ 1. source
1978        3 │ create table users(id int, email text);
1979          ╰╴             ───── 2. destination
1980        ");
1981    }
1982
1983    #[test]
1984    fn goto_select_column() {
1985        assert_snapshot!(goto("
1986create table users(id int, email text);
1987select id$0 from users;
1988"), @r"
1989          ╭▸ 
1990        2 │ create table users(id int, email text);
1991          │                    ── 2. destination
1992        3 │ select id from users;
1993          ╰╴        ─ 1. source
1994        ");
1995    }
1996
1997    #[test]
1998    fn goto_select_column_second() {
1999        assert_snapshot!(goto("
2000create table users(id int, email text);
2001select id, email$0 from users;
2002"), @r"
2003          ╭▸ 
2004        2 │ create table users(id int, email text);
2005          │                            ───── 2. destination
2006        3 │ select id, email from users;
2007          ╰╴               ─ 1. source
2008        ");
2009    }
2010
2011    #[test]
2012    fn goto_select_column_with_schema() {
2013        assert_snapshot!(goto("
2014create table public.users(id int, email text);
2015select email$0 from public.users;
2016"), @r"
2017          ╭▸ 
2018        2 │ create table public.users(id int, email text);
2019          │                                   ───── 2. destination
2020        3 │ select email from public.users;
2021          ╰╴           ─ 1. source
2022        ");
2023    }
2024
2025    #[test]
2026    fn goto_select_column_with_search_path() {
2027        assert_snapshot!(goto("
2028set search_path to foo;
2029create table foo.users(id int, email text);
2030select id$0 from users;
2031"), @r"
2032          ╭▸ 
2033        3 │ create table foo.users(id int, email text);
2034          │                        ── 2. destination
2035        4 │ select id from users;
2036          ╰╴        ─ 1. source
2037        ");
2038    }
2039
2040    #[test]
2041    fn goto_select_table_as_column() {
2042        assert_snapshot!(goto("
2043create table t(x bigint, y bigint);
2044select t$0 from t;
2045"), @r"
2046          ╭▸ 
2047        2 │ create table t(x bigint, y bigint);
2048          │              ─ 2. destination
2049        3 │ select t from t;
2050          ╰╴       ─ 1. source
2051        ");
2052    }
2053
2054    #[test]
2055    fn goto_select_table_as_column_with_schema() {
2056        assert_snapshot!(goto("
2057create table public.t(x bigint, y bigint);
2058select t$0 from public.t;
2059"), @r"
2060          ╭▸ 
2061        2 │ create table public.t(x bigint, y bigint);
2062          │                     ─ 2. destination
2063        3 │ select t from public.t;
2064          ╰╴       ─ 1. source
2065        ");
2066    }
2067
2068    #[test]
2069    fn goto_select_table_as_column_with_search_path() {
2070        assert_snapshot!(goto("
2071set search_path to foo;
2072create table foo.users(id int, email text);
2073select users$0 from users;
2074"), @r"
2075          ╭▸ 
2076        3 │ create table foo.users(id int, email text);
2077          │                  ───── 2. destination
2078        4 │ select users from users;
2079          ╰╴           ─ 1. source
2080        ");
2081    }
2082
2083    #[test]
2084    fn goto_select_column_with_same_name_as_table() {
2085        assert_snapshot!(goto("
2086create table t(t int);
2087select t$0 from t;
2088"), @r"
2089          ╭▸ 
2090        2 │ create table t(t int);
2091          │                ─ 2. destination
2092        3 │ select t from t;
2093          ╰╴       ─ 1. source
2094        ");
2095    }
2096
2097    #[test]
2098    fn goto_drop_schema() {
2099        assert_snapshot!(goto("
2100create schema foo;
2101drop schema foo$0;
2102"), @r"
2103          ╭▸ 
2104        2 │ create schema foo;
2105          │               ─── 2. destination
2106        3 │ drop schema foo;
2107          ╰╴              ─ 1. source
2108        ");
2109    }
2110
2111    #[test]
2112    fn goto_drop_schema_defined_after() {
2113        assert_snapshot!(goto("
2114drop schema foo$0;
2115create schema foo;
2116"), @r"
2117          ╭▸ 
2118        2 │ drop schema foo;
2119          │               ─ 1. source
2120        3 │ create schema foo;
2121          ╰╴              ─── 2. destination
2122        ");
2123    }
2124
2125    #[test]
2126    fn goto_schema_qualifier_in_table() {
2127        assert_snapshot!(goto("
2128create schema foo;
2129create table foo$0.t(a int);
2130"), @r"
2131          ╭▸ 
2132        2 │ create schema foo;
2133          │               ─── 2. destination
2134        3 │ create table foo.t(a int);
2135          ╰╴               ─ 1. source
2136        ");
2137    }
2138
2139    #[test]
2140    fn goto_schema_qualifier_in_drop_table() {
2141        assert_snapshot!(goto("
2142create schema foo;
2143create table foo.t(a int);
2144drop table foo$0.t;
2145"), @r"
2146          ╭▸ 
2147        2 │ create schema foo;
2148          │               ─── 2. destination
2149        3 │ create table foo.t(a int);
2150        4 │ drop table foo.t;
2151          ╰╴             ─ 1. source
2152        ");
2153    }
2154
2155    #[test]
2156    fn goto_schema_qualifier_multiple_schemas() {
2157        assert_snapshot!(goto("
2158create schema foo;
2159create schema bar;
2160create table bar$0.t(a int);
2161"), @r"
2162          ╭▸ 
2163        3 │ create schema bar;
2164          │               ─── 2. destination
2165        4 │ create table bar.t(a int);
2166          ╰╴               ─ 1. source
2167        ");
2168    }
2169
2170    #[test]
2171    fn goto_schema_qualifier_in_function_call() {
2172        assert_snapshot!(goto(r#"
2173create schema foo;
2174create function foo.bar() returns int as $$ begin return 1; end; $$ language plpgsql;
2175select foo$0.bar();
2176"#), @r"
2177          ╭▸ 
2178        2 │ create schema foo;
2179          │               ─── 2. destination
2180        3 │ create function foo.bar() returns int as $$ begin return 1; end; $$ language plpgsql;
2181        4 │ select foo.bar();
2182          ╰╴         ─ 1. source
2183        ");
2184    }
2185
2186    #[test]
2187    fn goto_schema_qualifier_in_function_call_from_clause() {
2188        assert_snapshot!(goto(r#"
2189create schema myschema;
2190create function myschema.get_data() returns table(id int) as $$ begin return query select 1; end; $$ language plpgsql;
2191select * from myschema$0.get_data();
2192"#), @r"
2193          ╭▸ 
2194        2 │ create schema myschema;
2195          │               ──────── 2. destination
2196        3 │ create function myschema.get_data() returns table(id int) as $$ begin return query select 1; end; $$ language plpgsql;
2197        4 │ select * from myschema.get_data();
2198          ╰╴                     ─ 1. source
2199        ");
2200    }
2201
2202    #[test]
2203    fn goto_schema_qualifier_in_select_from() {
2204        assert_snapshot!(goto("
2205create schema foo;
2206create table foo.t(x int);
2207select x from foo$0.t;
2208"), @r"
2209          ╭▸ 
2210        2 │ create schema foo;
2211          │               ─── 2. destination
2212        3 │ create table foo.t(x int);
2213        4 │ select x from foo.t;
2214          ╰╴                ─ 1. source
2215        ");
2216    }
2217
2218    #[test]
2219    fn goto_qualified_column_table() {
2220        assert_snapshot!(goto("
2221create table t(a int);
2222select t$0.a from t;
2223"), @r"
2224          ╭▸ 
2225        2 │ create table t(a int);
2226          │              ─ 2. destination
2227        3 │ select t.a from t;
2228          ╰╴       ─ 1. source
2229        ");
2230    }
2231
2232    #[test]
2233    fn goto_qualified_column_column() {
2234        assert_snapshot!(goto("
2235create table t(a int);
2236select t.a$0 from t;
2237"), @r"
2238          ╭▸ 
2239        2 │ create table t(a int);
2240          │                ─ 2. destination
2241        3 │ select t.a from t;
2242          ╰╴         ─ 1. source
2243        ");
2244    }
2245
2246    #[test]
2247    fn goto_three_part_qualified_column_schema() {
2248        assert_snapshot!(goto("
2249create schema foo;
2250create table foo.t(a int);
2251select foo$0.t.a from t;
2252"), @r"
2253          ╭▸ 
2254        2 │ create schema foo;
2255          │               ─── 2. destination
2256        3 │ create table foo.t(a int);
2257        4 │ select foo.t.a from t;
2258          ╰╴         ─ 1. source
2259        ");
2260    }
2261
2262    #[test]
2263    fn goto_three_part_qualified_column_table() {
2264        assert_snapshot!(goto("
2265create schema foo;
2266create table foo.t(a int);
2267select foo.t$0.a from t;
2268"), @r"
2269          ╭▸ 
2270        3 │ create table foo.t(a int);
2271          │                  ─ 2. destination
2272        4 │ select foo.t.a from t;
2273          ╰╴           ─ 1. source
2274        ");
2275    }
2276
2277    #[test]
2278    fn goto_three_part_qualified_column_column() {
2279        assert_snapshot!(goto("
2280create schema foo;
2281create table foo.t(a int);
2282select foo.t.a$0 from t;
2283"), @r"
2284          ╭▸ 
2285        3 │ create table foo.t(a int);
2286          │                    ─ 2. destination
2287        4 │ select foo.t.a from t;
2288          ╰╴             ─ 1. source
2289        ");
2290    }
2291
2292    #[test]
2293    fn goto_cte_values_column1() {
2294        assert_snapshot!(goto("
2295with t as (
2296    values (1, 2), (3, 4)
2297)
2298select column1$0, column2 from t;
2299"), @r"
2300          ╭▸ 
2301        3 │     values (1, 2), (3, 4)
2302          │             ─ 2. destination
2303        4 │ )
2304        5 │ select column1, column2 from t;
2305          ╰╴             ─ 1. source
2306        ");
2307    }
2308
2309    #[test]
2310    fn goto_cte_values_column2() {
2311        assert_snapshot!(goto("
2312with t as (
2313    values (1, 2), (3, 4)
2314)
2315select column1, column2$0 from t;
2316"), @r"
2317          ╭▸ 
2318        3 │     values (1, 2), (3, 4)
2319          │                ─ 2. destination
2320        4 │ )
2321        5 │ select column1, column2 from t;
2322          ╰╴                      ─ 1. source
2323        ");
2324    }
2325
2326    #[test]
2327    fn goto_cte_values_single_column() {
2328        assert_snapshot!(goto("
2329with t as (
2330    values (1), (2), (3)
2331)
2332select column1$0 from t;
2333"), @r"
2334          ╭▸ 
2335        3 │     values (1), (2), (3)
2336          │             ─ 2. destination
2337        4 │ )
2338        5 │ select column1 from t;
2339          ╰╴             ─ 1. source
2340        ");
2341    }
2342
2343    #[test]
2344    fn goto_cte_values_multiple_rows() {
2345        assert_snapshot!(goto("
2346with t as (
2347    values
2348        (1, 2, 3),
2349        (4, 5, 6),
2350        (7, 8, 9)
2351)
2352select column3$0 from t;
2353"), @r"
2354          ╭▸ 
2355        4 │         (1, 2, 3),
2356          │                ─ 2. destination
23572358        8 │ select column3 from t;
2359          ╰╴             ─ 1. source
2360        ");
2361    }
2362
2363    #[test]
2364    fn goto_cte_values_uppercase_column_names() {
2365        assert_snapshot!(goto("
2366with t as (
2367    values (1, 2), (3, 4)
2368)
2369select COLUMN1$0, COLUMN2 from t;
2370"), @r"
2371          ╭▸ 
2372        3 │     values (1, 2), (3, 4)
2373          │             ─ 2. destination
2374        4 │ )
2375        5 │ select COLUMN1, COLUMN2 from t;
2376          ╰╴             ─ 1. source
2377        ");
2378    }
2379
2380    #[test]
2381    fn goto_qualified_column_with_schema_in_from_table() {
2382        assert_snapshot!(goto("
2383create table foo.t(a int, b int);
2384select t$0.a from foo.t;
2385"), @r"
2386          ╭▸ 
2387        2 │ create table foo.t(a int, b int);
2388          │                  ─ 2. destination
2389        3 │ select t.a from foo.t;
2390          ╰╴       ─ 1. source
2391        ");
2392    }
2393
2394    #[test]
2395    fn goto_qualified_column_with_schema_in_from_column() {
2396        assert_snapshot!(goto("
2397create table foo.t(a int, b int);
2398select t.a$0 from foo.t;
2399"), @r"
2400          ╭▸ 
2401        2 │ create table foo.t(a int, b int);
2402          │                    ─ 2. destination
2403        3 │ select t.a from foo.t;
2404          ╰╴         ─ 1. source
2405        ");
2406    }
2407
2408    #[test]
2409    fn goto_cte_union_all_column() {
2410        assert_snapshot!(goto("
2411with t as (
2412    select 1 as a, 2 as b
2413    union all
2414    select 3, 4
2415)
2416select a$0, b from t;
2417"), @r"
2418          ╭▸ 
2419        3 │     select 1 as a, 2 as b
2420          │                 ─ 2. destination
24212422        7 │ select a, b from t;
2423          ╰╴       ─ 1. source
2424        ");
2425    }
2426
2427    #[test]
2428    fn goto_cte_union_all_column_second() {
2429        assert_snapshot!(goto("
2430with t as (
2431    select 1 as a, 2 as b
2432    union all
2433    select 3, 4
2434)
2435select a, b$0 from t;
2436"), @r"
2437          ╭▸ 
2438        3 │     select 1 as a, 2 as b
2439          │                         ─ 2. destination
24402441        7 │ select a, b from t;
2442          ╰╴          ─ 1. source
2443        ");
2444    }
2445
2446    #[test]
2447    fn goto_cte_union_column() {
2448        assert_snapshot!(goto("
2449with t as (
2450    select 1 as a, 2 as b
2451    union
2452    select 3, 4
2453)
2454select a$0 from t;
2455"), @r"
2456          ╭▸ 
2457        3 │     select 1 as a, 2 as b
2458          │                 ─ 2. destination
24592460        7 │ select a from t;
2461          ╰╴       ─ 1. source
2462        ");
2463    }
2464
2465    #[test]
2466    fn goto_drop_aggregate() {
2467        assert_snapshot!(goto("
2468create aggregate myavg(int) (sfunc = int4_avg_accum, stype = _int8);
2469drop aggregate myavg$0(int);
2470"), @r"
2471          ╭▸ 
2472        2 │ create aggregate myavg(int) (sfunc = int4_avg_accum, stype = _int8);
2473          │                  ───── 2. destination
2474        3 │ drop aggregate myavg(int);
2475          ╰╴                   ─ 1. source
2476        ");
2477    }
2478
2479    #[test]
2480    fn goto_drop_aggregate_with_schema() {
2481        assert_snapshot!(goto("
2482set search_path to public;
2483create aggregate myavg(int) (sfunc = int4_avg_accum, stype = _int8);
2484drop aggregate public.myavg$0(int);
2485"), @r"
2486          ╭▸ 
2487        3 │ create aggregate myavg(int) (sfunc = int4_avg_accum, stype = _int8);
2488          │                  ───── 2. destination
2489        4 │ drop aggregate public.myavg(int);
2490          ╰╴                          ─ 1. source
2491        ");
2492    }
2493
2494    #[test]
2495    fn goto_drop_aggregate_defined_after() {
2496        assert_snapshot!(goto("
2497drop aggregate myavg$0(int);
2498create aggregate myavg(int) (sfunc = int4_avg_accum, stype = _int8);
2499"), @r"
2500          ╭▸ 
2501        2 │ drop aggregate myavg(int);
2502          │                    ─ 1. source
2503        3 │ create aggregate myavg(int) (sfunc = int4_avg_accum, stype = _int8);
2504          ╰╴                 ───── 2. destination
2505        ");
2506    }
2507
2508    #[test]
2509    fn goto_aggregate_definition_returns_self() {
2510        assert_snapshot!(goto("
2511create aggregate myavg$0(int) (sfunc = int4_avg_accum, stype = _int8);
2512"), @r"
2513          ╭▸ 
2514        2 │ create aggregate myavg(int) (sfunc = int4_avg_accum, stype = _int8);
2515          │                  ┬───┬
2516          │                  │   │
2517          │                  │   1. source
2518          ╰╴                 2. destination
2519        ");
2520    }
2521
2522    #[test]
2523    fn goto_drop_aggregate_with_search_path() {
2524        assert_snapshot!(goto("
2525create aggregate myavg(int) (sfunc = int4_avg_accum, stype = _int8);
2526set search_path to bar;
2527create aggregate myavg(int) (sfunc = int4_avg_accum, stype = _int8);
2528set search_path to default;
2529drop aggregate myavg$0(int);
2530"), @r"
2531          ╭▸ 
2532        2 │ create aggregate myavg(int) (sfunc = int4_avg_accum, stype = _int8);
2533          │                  ───── 2. destination
25342535        6 │ drop aggregate myavg(int);
2536          ╰╴                   ─ 1. source
2537        ");
2538    }
2539
2540    #[test]
2541    fn goto_drop_aggregate_multiple() {
2542        assert_snapshot!(goto("
2543create aggregate avg1(int) (sfunc = int4_avg_accum, stype = _int8);
2544create aggregate avg2(int) (sfunc = int4_avg_accum, stype = _int8);
2545drop aggregate avg1(int), avg2$0(int);
2546"), @r"
2547          ╭▸ 
2548        3 │ create aggregate avg2(int) (sfunc = int4_avg_accum, stype = _int8);
2549          │                  ──── 2. destination
2550        4 │ drop aggregate avg1(int), avg2(int);
2551          ╰╴                             ─ 1. source
2552        ");
2553    }
2554
2555    #[test]
2556    fn goto_drop_aggregate_overloaded() {
2557        assert_snapshot!(goto("
2558create aggregate sum(complex) (sfunc = complex_add, stype = complex, initcond = '(0,0)');
2559create aggregate sum(bigint) (sfunc = bigint_add, stype = bigint, initcond = '0');
2560drop aggregate sum$0(complex);
2561"), @r"
2562          ╭▸ 
2563        2 │ create aggregate sum(complex) (sfunc = complex_add, stype = complex, initcond = '(0,0)');
2564          │                  ─── 2. destination
2565        3 │ create aggregate sum(bigint) (sfunc = bigint_add, stype = bigint, initcond = '0');
2566        4 │ drop aggregate sum(complex);
2567          ╰╴                 ─ 1. source
2568        ");
2569    }
2570
2571    #[test]
2572    fn goto_drop_aggregate_second_overload() {
2573        assert_snapshot!(goto("
2574create aggregate sum(complex) (sfunc = complex_add, stype = complex, initcond = '(0,0)');
2575create aggregate sum(bigint) (sfunc = bigint_add, stype = bigint, initcond = '0');
2576drop aggregate sum$0(bigint);
2577"), @r"
2578          ╭▸ 
2579        3 │ create aggregate sum(bigint) (sfunc = bigint_add, stype = bigint, initcond = '0');
2580          │                  ─── 2. destination
2581        4 │ drop aggregate sum(bigint);
2582          ╰╴                 ─ 1. source
2583        ");
2584    }
2585
2586    #[test]
2587    fn goto_drop_routine_function() {
2588        assert_snapshot!(goto("
2589create function foo() returns int as $$ select 1 $$ language sql;
2590drop routine foo$0();
2591"), @r"
2592          ╭▸ 
2593        2 │ create function foo() returns int as $$ select 1 $$ language sql;
2594          │                 ─── 2. destination
2595        3 │ drop routine foo();
2596          ╰╴               ─ 1. source
2597        ");
2598    }
2599
2600    #[test]
2601    fn goto_drop_routine_aggregate() {
2602        assert_snapshot!(goto("
2603create aggregate myavg(int) (sfunc = int4_avg_accum, stype = _int8);
2604drop routine myavg$0(int);
2605"), @r"
2606          ╭▸ 
2607        2 │ create aggregate myavg(int) (sfunc = int4_avg_accum, stype = _int8);
2608          │                  ───── 2. destination
2609        3 │ drop routine myavg(int);
2610          ╰╴                 ─ 1. source
2611        ");
2612    }
2613
2614    #[test]
2615    fn goto_drop_routine_with_schema() {
2616        assert_snapshot!(goto("
2617set search_path to public;
2618create function foo() returns int as $$ select 1 $$ language sql;
2619drop routine public.foo$0();
2620"), @r"
2621          ╭▸ 
2622        3 │ create function foo() returns int as $$ select 1 $$ language sql;
2623          │                 ─── 2. destination
2624        4 │ drop routine public.foo();
2625          ╰╴                      ─ 1. source
2626        ");
2627    }
2628
2629    #[test]
2630    fn goto_drop_routine_defined_after() {
2631        assert_snapshot!(goto("
2632drop routine foo$0();
2633create function foo() returns int as $$ select 1 $$ language sql;
2634"), @r"
2635          ╭▸ 
2636        2 │ drop routine foo();
2637          │                ─ 1. source
2638        3 │ create function foo() returns int as $$ select 1 $$ language sql;
2639          ╰╴                ─── 2. destination
2640        ");
2641    }
2642
2643    #[test]
2644    fn goto_drop_routine_with_search_path() {
2645        assert_snapshot!(goto("
2646create function foo() returns int as $$ select 1 $$ language sql;
2647set search_path to bar;
2648create function foo() returns int as $$ select 1 $$ language sql;
2649set search_path to default;
2650drop routine foo$0();
2651"), @r"
2652          ╭▸ 
2653        2 │ create function foo() returns int as $$ select 1 $$ language sql;
2654          │                 ─── 2. destination
26552656        6 │ drop routine foo();
2657          ╰╴               ─ 1. source
2658        ");
2659    }
2660
2661    #[test]
2662    fn goto_drop_routine_overloaded() {
2663        assert_snapshot!(goto("
2664create function add(complex) returns complex as $$ select null $$ language sql;
2665create function add(bigint) returns bigint as $$ select 1 $$ language sql;
2666drop routine add$0(complex);
2667"), @r"
2668          ╭▸ 
2669        2 │ create function add(complex) returns complex as $$ select null $$ language sql;
2670          │                 ─── 2. destination
2671        3 │ create function add(bigint) returns bigint as $$ select 1 $$ language sql;
2672        4 │ drop routine add(complex);
2673          ╰╴               ─ 1. source
2674        ");
2675    }
2676
2677    #[test]
2678    fn goto_drop_routine_second_overload() {
2679        assert_snapshot!(goto("
2680create function add(complex) returns complex as $$ select null $$ language sql;
2681create function add(bigint) returns bigint as $$ select 1 $$ language sql;
2682drop routine add$0(bigint);
2683"), @r"
2684          ╭▸ 
2685        3 │ create function add(bigint) returns bigint as $$ select 1 $$ language sql;
2686          │                 ─── 2. destination
2687        4 │ drop routine add(bigint);
2688          ╰╴               ─ 1. source
2689        ");
2690    }
2691
2692    #[test]
2693    fn goto_drop_routine_aggregate_overloaded() {
2694        assert_snapshot!(goto("
2695create aggregate sum(complex) (sfunc = complex_add, stype = complex, initcond = '(0,0)');
2696create aggregate sum(bigint) (sfunc = bigint_add, stype = bigint, initcond = '0');
2697drop routine sum$0(complex);
2698"), @r"
2699          ╭▸ 
2700        2 │ create aggregate sum(complex) (sfunc = complex_add, stype = complex, initcond = '(0,0)');
2701          │                  ─── 2. destination
2702        3 │ create aggregate sum(bigint) (sfunc = bigint_add, stype = bigint, initcond = '0');
2703        4 │ drop routine sum(complex);
2704          ╰╴               ─ 1. source
2705        ");
2706    }
2707
2708    #[test]
2709    fn goto_drop_routine_multiple() {
2710        assert_snapshot!(goto("
2711create function foo() returns int as $$ select 1 $$ language sql;
2712create function bar() returns int as $$ select 1 $$ language sql;
2713drop routine foo(), bar$0();
2714"), @r"
2715          ╭▸ 
2716        3 │ create function bar() returns int as $$ select 1 $$ language sql;
2717          │                 ─── 2. destination
2718        4 │ drop routine foo(), bar();
2719          ╰╴                      ─ 1. source
2720        ");
2721    }
2722
2723    #[test]
2724    fn goto_drop_procedure() {
2725        assert_snapshot!(goto("
2726create procedure foo() language sql as $$ select 1 $$;
2727drop procedure foo$0();
2728"), @r"
2729          ╭▸ 
2730        2 │ create procedure foo() language sql as $$ select 1 $$;
2731          │                  ─── 2. destination
2732        3 │ drop procedure foo();
2733          ╰╴                 ─ 1. source
2734        ");
2735    }
2736
2737    #[test]
2738    fn goto_drop_procedure_with_schema() {
2739        assert_snapshot!(goto("
2740set search_path to public;
2741create procedure foo() language sql as $$ select 1 $$;
2742drop procedure public.foo$0();
2743"), @r"
2744          ╭▸ 
2745        3 │ create procedure foo() language sql as $$ select 1 $$;
2746          │                  ─── 2. destination
2747        4 │ drop procedure public.foo();
2748          ╰╴                        ─ 1. source
2749        ");
2750    }
2751
2752    #[test]
2753    fn goto_drop_procedure_defined_after() {
2754        assert_snapshot!(goto("
2755drop procedure foo$0();
2756create procedure foo() language sql as $$ select 1 $$;
2757"), @r"
2758          ╭▸ 
2759        2 │ drop procedure foo();
2760          │                  ─ 1. source
2761        3 │ create procedure foo() language sql as $$ select 1 $$;
2762          ╰╴                 ─── 2. destination
2763        ");
2764    }
2765
2766    #[test]
2767    fn goto_drop_procedure_with_search_path() {
2768        assert_snapshot!(goto("
2769create procedure foo() language sql as $$ select 1 $$;
2770set search_path to bar;
2771create procedure foo() language sql as $$ select 1 $$;
2772set search_path to default;
2773drop procedure foo$0();
2774"), @r"
2775          ╭▸ 
2776        2 │ create procedure foo() language sql as $$ select 1 $$;
2777          │                  ─── 2. destination
27782779        6 │ drop procedure foo();
2780          ╰╴                 ─ 1. source
2781        ");
2782    }
2783
2784    #[test]
2785    fn goto_drop_procedure_overloaded() {
2786        assert_snapshot!(goto("
2787create procedure add(complex) language sql as $$ select null $$;
2788create procedure add(bigint) language sql as $$ select 1 $$;
2789drop procedure add$0(complex);
2790"), @r"
2791          ╭▸ 
2792        2 │ create procedure add(complex) language sql as $$ select null $$;
2793          │                  ─── 2. destination
2794        3 │ create procedure add(bigint) language sql as $$ select 1 $$;
2795        4 │ drop procedure add(complex);
2796          ╰╴                 ─ 1. source
2797        ");
2798    }
2799
2800    #[test]
2801    fn goto_drop_procedure_second_overload() {
2802        assert_snapshot!(goto("
2803create procedure add(complex) language sql as $$ select null $$;
2804create procedure add(bigint) language sql as $$ select 1 $$;
2805drop procedure add$0(bigint);
2806"), @r"
2807          ╭▸ 
2808        3 │ create procedure add(bigint) language sql as $$ select 1 $$;
2809          │                  ─── 2. destination
2810        4 │ drop procedure add(bigint);
2811          ╰╴                 ─ 1. source
2812        ");
2813    }
2814
2815    #[test]
2816    fn goto_drop_procedure_multiple() {
2817        assert_snapshot!(goto("
2818create procedure foo() language sql as $$ select 1 $$;
2819create procedure bar() language sql as $$ select 1 $$;
2820drop procedure foo(), bar$0();
2821"), @r"
2822          ╭▸ 
2823        3 │ create procedure bar() language sql as $$ select 1 $$;
2824          │                  ─── 2. destination
2825        4 │ drop procedure foo(), bar();
2826          ╰╴                        ─ 1. source
2827        ");
2828    }
2829
2830    #[test]
2831    fn goto_procedure_definition_returns_self() {
2832        assert_snapshot!(goto("
2833create procedure foo$0() language sql as $$ select 1 $$;
2834"), @r"
2835          ╭▸ 
2836        2 │ create procedure foo() language sql as $$ select 1 $$;
2837          │                  ┬─┬
2838          │                  │ │
2839          │                  │ 1. source
2840          ╰╴                 2. destination
2841        ");
2842    }
2843
2844    #[test]
2845    fn goto_call_procedure() {
2846        assert_snapshot!(goto("
2847create procedure foo() language sql as $$ select 1 $$;
2848call foo$0();
2849"), @r"
2850          ╭▸ 
2851        2 │ create procedure foo() language sql as $$ select 1 $$;
2852          │                  ─── 2. destination
2853        3 │ call foo();
2854          ╰╴       ─ 1. source
2855        ");
2856    }
2857
2858    #[test]
2859    fn goto_call_procedure_with_schema() {
2860        assert_snapshot!(goto("
2861create procedure public.foo() language sql as $$ select 1 $$;
2862call public.foo$0();
2863"), @r"
2864          ╭▸ 
2865        2 │ create procedure public.foo() language sql as $$ select 1 $$;
2866          │                         ─── 2. destination
2867        3 │ call public.foo();
2868          ╰╴              ─ 1. source
2869        ");
2870    }
2871
2872    #[test]
2873    fn goto_call_procedure_with_search_path() {
2874        assert_snapshot!(goto("
2875set search_path to myschema;
2876create procedure foo() language sql as $$ select 1 $$;
2877call myschema.foo$0();
2878"), @r"
2879          ╭▸ 
2880        3 │ create procedure foo() language sql as $$ select 1 $$;
2881          │                  ─── 2. destination
2882        4 │ call myschema.foo();
2883          ╰╴                ─ 1. source
2884        ");
2885    }
2886
2887    #[test]
2888    fn goto_drop_routine_procedure() {
2889        assert_snapshot!(goto("
2890create procedure foo() language sql as $$ select 1 $$;
2891drop routine foo$0();
2892"), @r"
2893          ╭▸ 
2894        2 │ create procedure foo() language sql as $$ select 1 $$;
2895          │                  ─── 2. destination
2896        3 │ drop routine foo();
2897          ╰╴               ─ 1. source
2898        ");
2899    }
2900
2901    #[test]
2902    fn goto_drop_routine_prefers_function_over_procedure() {
2903        assert_snapshot!(goto("
2904create function foo() returns int as $$ select 1 $$ language sql;
2905create procedure foo() language sql as $$ select 1 $$;
2906drop routine foo$0();
2907"), @r"
2908          ╭▸ 
2909        2 │ create function foo() returns int as $$ select 1 $$ language sql;
2910          │                 ─── 2. destination
2911        3 │ create procedure foo() language sql as $$ select 1 $$;
2912        4 │ drop routine foo();
2913          ╰╴               ─ 1. source
2914        ");
2915    }
2916
2917    #[test]
2918    fn goto_drop_routine_prefers_aggregate_over_procedure() {
2919        assert_snapshot!(goto("
2920create aggregate foo(int) (sfunc = int4_avg_accum, stype = _int8);
2921create procedure foo(int) language sql as $$ select 1 $$;
2922drop routine foo$0(int);
2923"), @r"
2924          ╭▸ 
2925        2 │ create aggregate foo(int) (sfunc = int4_avg_accum, stype = _int8);
2926          │                  ─── 2. destination
2927        3 │ create procedure foo(int) language sql as $$ select 1 $$;
2928        4 │ drop routine foo(int);
2929          ╰╴               ─ 1. source
2930        ");
2931    }
2932
2933    #[test]
2934    fn goto_table_alias_in_qualified_column() {
2935        assert_snapshot!(goto("
2936create table t(a int8, b text);
2937select f$0.a from t as f;
2938"), @r"
2939          ╭▸ 
2940        3 │ select f.a from t as f;
2941          ╰╴       ─ 1. source   ─ 2. destination
2942        ");
2943    }
2944
2945    #[test]
2946    fn goto_column_through_table_alias() {
2947        assert_snapshot!(goto("
2948create table t(a int8, b text);
2949select f.a$0 from t as f;
2950"), @r"
2951          ╭▸ 
2952        2 │ create table t(a int8, b text);
2953          │                ─ 2. destination
2954        3 │ select f.a from t as f;
2955          ╰╴         ─ 1. source
2956        ");
2957    }
2958
2959    #[test]
2960    fn goto_cte_alias_renamed_column() {
2961        assert_snapshot!(goto("
2962with t as (select 1 a, 2 b)
2963select f.x$0 from t as f(x);
2964"), @r"
2965          ╭▸ 
2966        3 │ select f.x from t as f(x);
2967          ╰╴         ─ 1. source   ─ 2. destination
2968        ");
2969    }
2970
2971    #[test]
2972    fn goto_cte_alias_unrenamed_column() {
2973        assert_snapshot!(goto("
2974with t as (select 1 a, 2 b)
2975select f.b$0 from t as f(x);
2976"), @r"
2977          ╭▸ 
2978        2 │ with t as (select 1 a, 2 b)
2979          │                          ─ 2. destination
2980        3 │ select f.b from t as f(x);
2981          ╰╴         ─ 1. source
2982        ");
2983    }
2984
2985    #[test]
2986    fn goto_join_table() {
2987        assert_snapshot!(goto("
2988create table users(id int, email text);
2989create table messages(id int, user_id int, message text);
2990select * from users join messages$0 on users.id = messages.user_id;
2991"), @r"
2992          ╭▸ 
2993        3 │ create table messages(id int, user_id int, message text);
2994          │              ──────── 2. destination
2995        4 │ select * from users join messages on users.id = messages.user_id;
2996          ╰╴                                ─ 1. source
2997        ");
2998    }
2999
3000    #[test]
3001    fn goto_join_qualified_column_from_joined_table() {
3002        assert_snapshot!(goto("
3003create table users(id int, email text);
3004create table messages(id int, user_id int, message text);
3005select messages.user_id$0 from users join messages on users.id = messages.user_id;
3006"), @r"
3007          ╭▸ 
3008        3 │ create table messages(id int, user_id int, message text);
3009          │                               ─────── 2. destination
3010        4 │ select messages.user_id from users join messages on users.id = messages.user_id;
3011          ╰╴                      ─ 1. source
3012        ");
3013    }
3014
3015    #[test]
3016    fn goto_join_qualified_column_from_base_table() {
3017        assert_snapshot!(goto("
3018create table users(id int, email text);
3019create table messages(id int, user_id int, message text);
3020select users.id$0 from users join messages on users.id = messages.user_id;
3021"), @r"
3022          ╭▸ 
3023        2 │ create table users(id int, email text);
3024          │                    ── 2. destination
3025        3 │ create table messages(id int, user_id int, message text);
3026        4 │ select users.id from users join messages on users.id = messages.user_id;
3027          ╰╴              ─ 1. source
3028        ");
3029    }
3030
3031    #[test]
3032    fn goto_join_multiple_joins() {
3033        assert_snapshot!(goto("
3034create table users(id int, name text);
3035create table messages(id int, user_id int, message text);
3036create table comments(id int, message_id int, text text);
3037select comments.text$0 from users
3038  join messages on users.id = messages.user_id
3039  join comments on messages.id = comments.message_id;
3040"), @r"
3041          ╭▸ 
3042        4 │ create table comments(id int, message_id int, text text);
3043          │                                               ──── 2. destination
3044        5 │ select comments.text from users
3045          ╰╴                   ─ 1. source
3046        ");
3047    }
3048
3049    #[test]
3050    fn goto_join_with_aliases() {
3051        assert_snapshot!(goto("
3052create table users(id int, name text);
3053create table messages(id int, user_id int, message text);
3054select m.message$0 from users as u join messages as m on u.id = m.user_id;
3055"), @r"
3056          ╭▸ 
3057        3 │ create table messages(id int, user_id int, message text);
3058          │                                            ─────── 2. destination
3059        4 │ select m.message from users as u join messages as m on u.id = m.user_id;
3060          ╰╴               ─ 1. source
3061        ");
3062    }
3063
3064    #[test]
3065    fn goto_join_unqualified_column() {
3066        assert_snapshot!(goto("
3067create table users(id int, email text);
3068create table messages(id int, user_id int, message text);
3069select message$0 from users join messages on users.id = messages.user_id;
3070"), @r"
3071          ╭▸ 
3072        3 │ create table messages(id int, user_id int, message text);
3073          │                                            ─────── 2. destination
3074        4 │ select message from users join messages on users.id = messages.user_id;
3075          ╰╴             ─ 1. source
3076        ");
3077    }
3078
3079    #[test]
3080    fn goto_join_with_many_tables() {
3081        assert_snapshot!(goto("
3082create table users(id int, email text);
3083create table messages(id int, user_id int, message text);
3084create table logins(id int, user_id int, at timestamptz);
3085create table posts(id int, user_id int, post text);
3086
3087select post$0 
3088  from users
3089    join messages 
3090      on users.id = messages.user_id
3091      join logins
3092        on users.id = logins.user_id
3093        join posts
3094          on users.id = posts.user_id
3095"), @r"
3096          ╭▸ 
3097        5 │ create table posts(id int, user_id int, post text);
3098          │                                         ──── 2. destination
3099        6 │
3100        7 │ select post 
3101          ╰╴          ─ 1. source
3102        ");
3103    }
3104
3105    #[test]
3106    fn goto_join_with_schema() {
3107        assert_snapshot!(goto("
3108create schema foo;
3109create table foo.users(id int, email text);
3110create table foo.messages(id int, user_id int, message text);
3111select foo.messages.message$0 from foo.users join foo.messages on foo.users.id = foo.messages.user_id;
3112"), @r"
3113          ╭▸ 
3114        4 │ create table foo.messages(id int, user_id int, message text);
3115          │                                                ─────── 2. destination
3116        5 │ select foo.messages.message from foo.users join foo.messages on foo.users.id = foo.messages.user_id;
3117          ╰╴                          ─ 1. source
3118        ");
3119    }
3120
3121    #[test]
3122    fn goto_join_left_join() {
3123        assert_snapshot!(goto("
3124create table users(id int, email text);
3125create table messages(id int, user_id int, message text);
3126select messages.message$0 from users left join messages on users.id = messages.user_id;
3127"), @r"
3128          ╭▸ 
3129        3 │ create table messages(id int, user_id int, message text);
3130          │                                            ─────── 2. destination
3131        4 │ select messages.message from users left join messages on users.id = messages.user_id;
3132          ╰╴                      ─ 1. source
3133        ");
3134    }
3135
3136    #[test]
3137    fn goto_insert_select_cte_column() {
3138        assert_snapshot!(goto("
3139create table users(id int, email text);
3140with new_data as (
3141    select 1 as id, 'test@example.com' as email
3142)
3143insert into users (id, email)
3144select id$0, email from new_data;
3145"), @r"
3146          ╭▸ 
3147        4 │     select 1 as id, 'test@example.com' as email
3148          │                 ── 2. destination
31493150        7 │ select id, email from new_data;
3151          ╰╴        ─ 1. source
3152        ");
3153    }
3154
3155    #[test]
3156    fn goto_insert_select_cte_column_second() {
3157        assert_snapshot!(goto("
3158create table users(id int, email text);
3159with new_data as (
3160    select 1 as id, 'test@example.com' as email
3161)
3162insert into users (id, email)
3163select id, email$0 from new_data;
3164"), @r"
3165          ╭▸ 
3166        4 │     select 1 as id, 'test@example.com' as email
3167          │                                           ───── 2. destination
31683169        7 │ select id, email from new_data;
3170          ╰╴               ─ 1. source
3171        ");
3172    }
3173
3174    #[test]
3175    fn goto_insert_select_cte_table() {
3176        assert_snapshot!(goto("
3177create table users(id int, email text);
3178with new_data as (
3179    select 1 as id, 'test@example.com' as email
3180)
3181insert into users (id, email)
3182select id, email from new_data$0;
3183"), @r"
3184          ╭▸ 
3185        3 │ with new_data as (
3186          │      ──────── 2. destination
31873188        7 │ select id, email from new_data;
3189          ╰╴                             ─ 1. source
3190        ");
3191    }
3192
3193    #[test]
3194    fn goto_delete_cte_column() {
3195        assert_snapshot!(goto("
3196create table users(id int, email text);
3197with old_data as (
3198    select 1 as id
3199)
3200delete from users where id in (select id$0 from old_data);
3201"), @r"
3202          ╭▸ 
3203        4 │     select 1 as id
3204          │                 ── 2. destination
3205        5 │ )
3206        6 │ delete from users where id in (select id from old_data);
3207          ╰╴                                       ─ 1. source
3208        ");
3209    }
3210
3211    #[test]
3212    fn goto_update_table() {
3213        assert_snapshot!(goto("
3214create table users(id int, email text);
3215update users$0 set email = 'new@example.com';
3216"), @r"
3217          ╭▸ 
3218        2 │ create table users(id int, email text);
3219          │              ───── 2. destination
3220        3 │ update users set email = 'new@example.com';
3221          ╰╴           ─ 1. source
3222        ");
3223    }
3224
3225    #[test]
3226    fn goto_update_table_with_schema() {
3227        assert_snapshot!(goto("
3228create table public.users(id int, email text);
3229update public.users$0 set email = 'new@example.com';
3230"), @r"
3231          ╭▸ 
3232        2 │ create table public.users(id int, email text);
3233          │                     ───── 2. destination
3234        3 │ update public.users set email = 'new@example.com';
3235          ╰╴                  ─ 1. source
3236        ");
3237    }
3238
3239    #[test]
3240    fn goto_update_table_with_search_path() {
3241        assert_snapshot!(goto("
3242set search_path to foo;
3243create table foo.users(id int, email text);
3244update users$0 set email = 'new@example.com';
3245"), @r"
3246          ╭▸ 
3247        3 │ create table foo.users(id int, email text);
3248          │                  ───── 2. destination
3249        4 │ update users set email = 'new@example.com';
3250          ╰╴           ─ 1. source
3251        ");
3252    }
3253
3254    #[test]
3255    fn goto_update_where_column() {
3256        assert_snapshot!(goto("
3257create table users(id int, email text);
3258update users set email = 'new@example.com' where id$0 = 1;
3259"), @r"
3260          ╭▸ 
3261        2 │ create table users(id int, email text);
3262          │                    ── 2. destination
3263        3 │ update users set email = 'new@example.com' where id = 1;
3264          ╰╴                                                  ─ 1. source
3265        ");
3266    }
3267
3268    #[test]
3269    fn goto_update_where_column_with_schema() {
3270        assert_snapshot!(goto("
3271create table public.users(id int, email text);
3272update public.users set email = 'new@example.com' where id$0 = 1;
3273"), @r"
3274          ╭▸ 
3275        2 │ create table public.users(id int, email text);
3276          │                           ── 2. destination
3277        3 │ update public.users set email = 'new@example.com' where id = 1;
3278          ╰╴                                                         ─ 1. source
3279        ");
3280    }
3281
3282    #[test]
3283    fn goto_update_where_column_with_search_path() {
3284        assert_snapshot!(goto("
3285set search_path to foo;
3286create table foo.users(id int, email text);
3287update users set email = 'new@example.com' where id$0 = 1;
3288"), @r"
3289          ╭▸ 
3290        3 │ create table foo.users(id int, email text);
3291          │                        ── 2. destination
3292        4 │ update users set email = 'new@example.com' where id = 1;
3293          ╰╴                                                  ─ 1. source
3294        ");
3295    }
3296
3297    #[test]
3298    fn goto_update_set_column() {
3299        assert_snapshot!(goto("
3300create table users(id int, email text);
3301update users set email$0 = 'new@example.com' where id = 1;
3302"), @r"
3303          ╭▸ 
3304        2 │ create table users(id int, email text);
3305          │                            ───── 2. destination
3306        3 │ update users set email = 'new@example.com' where id = 1;
3307          ╰╴                     ─ 1. source
3308        ");
3309    }
3310
3311    #[test]
3312    fn goto_update_set_column_with_schema() {
3313        assert_snapshot!(goto("
3314create table public.users(id int, email text);
3315update public.users set email$0 = 'new@example.com' where id = 1;
3316"), @r"
3317          ╭▸ 
3318        2 │ create table public.users(id int, email text);
3319          │                                   ───── 2. destination
3320        3 │ update public.users set email = 'new@example.com' where id = 1;
3321          ╰╴                            ─ 1. source
3322        ");
3323    }
3324
3325    #[test]
3326    fn goto_update_set_column_with_search_path() {
3327        assert_snapshot!(goto("
3328set search_path to foo;
3329create table foo.users(id int, email text);
3330update users set email$0 = 'new@example.com' where id = 1;
3331"), @r"
3332          ╭▸ 
3333        3 │ create table foo.users(id int, email text);
3334          │                                ───── 2. destination
3335        4 │ update users set email = 'new@example.com' where id = 1;
3336          ╰╴                     ─ 1. source
3337        ");
3338    }
3339
3340    #[test]
3341    fn goto_update_from_table() {
3342        assert_snapshot!(goto("
3343create table users(id int, email text);
3344create table messages(id int, user_id int, email text);
3345update users set email = messages.email from messages$0 where users.id = messages.user_id;
3346"), @r"
3347          ╭▸ 
3348        3 │ create table messages(id int, user_id int, email text);
3349          │              ──────── 2. destination
3350        4 │ update users set email = messages.email from messages where users.id = messages.user_id;
3351          ╰╴                                                    ─ 1. source
3352        ");
3353    }
3354
3355    #[test]
3356    fn goto_update_from_table_with_schema() {
3357        assert_snapshot!(goto("
3358create table users(id int, email text);
3359create table public.messages(id int, user_id int, email text);
3360update users set email = messages.email from public.messages$0 where users.id = messages.user_id;
3361"), @r"
3362          ╭▸ 
3363        3 │ create table public.messages(id int, user_id int, email text);
3364          │                     ──────── 2. destination
3365        4 │ update users set email = messages.email from public.messages where users.id = messages.user_id;
3366          ╰╴                                                           ─ 1. source
3367        ");
3368    }
3369
3370    #[test]
3371    fn goto_update_from_table_with_search_path() {
3372        assert_snapshot!(goto("
3373set search_path to foo;
3374create table users(id int, email text);
3375create table foo.messages(id int, user_id int, email text);
3376update users set email = messages.email from messages$0 where users.id = messages.user_id;
3377"), @r"
3378          ╭▸ 
3379        4 │ create table foo.messages(id int, user_id int, email text);
3380          │                  ──────── 2. destination
3381        5 │ update users set email = messages.email from messages where users.id = messages.user_id;
3382          ╰╴                                                    ─ 1. source
3383        ");
3384    }
3385
3386    #[test]
3387    fn goto_update_with_cte_table() {
3388        assert_snapshot!(goto("
3389create table users(id int, email text);
3390with new_data as (
3391    select 1 as id, 'new@example.com' as email
3392)
3393update users set email = new_data.email from new_data$0 where users.id = new_data.id;
3394"), @r"
3395          ╭▸ 
3396        3 │ with new_data as (
3397          │      ──────── 2. destination
33983399        6 │ update users set email = new_data.email from new_data where users.id = new_data.id;
3400          ╰╴                                                    ─ 1. source
3401        ");
3402    }
3403
3404    #[test]
3405    fn goto_update_with_cte_column_in_set() {
3406        assert_snapshot!(goto("
3407create table users(id int, email text);
3408with new_data as (
3409    select 1 as id, 'new@example.com' as email
3410)
3411update users set email = new_data.email$0 from new_data where users.id = new_data.id;
3412"), @r"
3413          ╭▸ 
3414        4 │     select 1 as id, 'new@example.com' as email
3415          │                                          ───── 2. destination
3416        5 │ )
3417        6 │ update users set email = new_data.email from new_data where users.id = new_data.id;
3418          ╰╴                                      ─ 1. source
3419        ");
3420    }
3421
3422    #[test]
3423    fn goto_update_with_cte_column_in_where() {
3424        assert_snapshot!(goto("
3425create table users(id int, email text);
3426with new_data as (
3427    select 1 as id, 'new@example.com' as email
3428)
3429update users set email = new_data.email from new_data where new_data.id$0 = users.id;
3430"), @r"
3431          ╭▸ 
3432        4 │     select 1 as id, 'new@example.com' as email
3433          │                 ── 2. destination
3434        5 │ )
3435        6 │ update users set email = new_data.email from new_data where new_data.id = users.id;
3436          ╰╴                                                                      ─ 1. source
3437        ");
3438    }
3439
3440    #[test]
3441    fn goto_update_with_cte_values() {
3442        assert_snapshot!(goto("
3443create table users(id int, email text);
3444with new_data as (
3445    values (1, 'new@example.com')
3446)
3447update users set email = new_data.column2$0 from new_data where users.id = new_data.column1;
3448"), @r"
3449          ╭▸ 
3450        4 │     values (1, 'new@example.com')
3451          │                ───────────────── 2. destination
3452        5 │ )
3453        6 │ update users set email = new_data.column2 from new_data where users.id = new_data.column1;
3454          ╰╴                                        ─ 1. source
3455        ");
3456    }
3457}