diff --git a/crates/squawk_ide/src/classify.rs b/crates/squawk_ide/src/classify.rs index 107412b1..55a9c6c5 100644 --- a/crates/squawk_ide/src/classify.rs +++ b/crates/squawk_ide/src/classify.rs @@ -130,6 +130,7 @@ pub(crate) fn classify_name_ref(name_ref: &ast::NameRef) -> Option .and_then(ast::FieldExpr::cast) .is_some(); + let mut in_arg_list = false; let mut in_from_clause = false; let mut in_on_clause = false; let mut in_returning_clause = false; @@ -137,6 +138,9 @@ pub(crate) fn classify_name_ref(name_ref: &ast::NameRef) -> Option let mut in_where_clause = false; let mut in_when_clause = false; for ancestor in parent.ancestors() { + if ast::ArgList::can_cast(ancestor.kind()) { + in_arg_list = true; + } if ast::OnClause::can_cast(ancestor.kind()) { in_on_clause = true; } @@ -191,7 +195,9 @@ pub(crate) fn classify_name_ref(name_ref: &ast::NameRef) -> Option } } } - if ast::Select::can_cast(ancestor.kind()) && (!in_from_clause || in_on_clause) { + if ast::Select::can_cast(ancestor.kind()) + && (!in_from_clause || in_on_clause || in_arg_list) + { if is_function_call || is_schema_table_col { return Some(NameRefClass::Schema); } else { @@ -607,6 +613,9 @@ pub(crate) fn classify_name_ref(name_ref: &ast::NameRef) -> Option return Some(NameRefClass::SelectFunctionCall); } if in_from_clause && !in_on_clause { + if in_arg_list { + return Some(NameRefClass::SelectColumn); + } return Some(NameRefClass::FromTable); } // Classify as SelectColumn for target list, WHERE, ORDER BY, GROUP BY, etc. diff --git a/crates/squawk_ide/src/goto_definition.rs b/crates/squawk_ide/src/goto_definition.rs index 8690e4e0..3c4226cc 100644 --- a/crates/squawk_ide/src/goto_definition.rs +++ b/crates/squawk_ide/src/goto_definition.rs @@ -550,6 +550,48 @@ select t$0.* from t; "); } + #[test] + fn goto_cross_join_func_column() { + assert_snapshot!(goto(r#" +with t(x) as (select $$[{"a":1,"b":2}]$$::json) +select * from t, json_to_recordset(x$0) as r(a int, b int); +"#), @r#" + ╭▸ + 2 │ with t(x) as (select $$[{"a":1,"b":2}]$$::json) + │ ─ 2. destination + 3 │ select * from t, json_to_recordset(x) as r(a int, b int); + ╰╴ ─ 1. source + "#); + } + + #[test] + fn goto_cross_join_func_qualified_column_table() { + assert_snapshot!(goto(r#" +with t(x) as (select $$[{"a":1,"b":2}]$$::json) +select * from t, json_to_recordset(t$0.x) as r(a int, b int); +"#), @r#" + ╭▸ + 2 │ with t(x) as (select $$[{"a":1,"b":2}]$$::json) + │ ─ 2. destination + 3 │ select * from t, json_to_recordset(t.x) as r(a int, b int); + ╰╴ ─ 1. source + "#); + } + + #[test] + fn goto_cross_join_func_qualified_column_field() { + assert_snapshot!(goto(r#" +with t(x) as (select $$[{"a":1,"b":2}]$$::json) +select * from t, json_to_recordset(t.x$0) as r(a int, b int); +"#), @r#" + ╭▸ + 2 │ with t(x) as (select $$[{"a":1,"b":2}]$$::json) + │ ─ 2. destination + 3 │ select * from t, json_to_recordset(t.x) as r(a int, b int); + ╰╴ ─ 1. source + "#); + } + #[test] fn goto_drop_sequence() { assert_snapshot!(goto("