diff --git a/core/translate/expr.rs b/core/translate/expr.rs index d9f2eb6d0..f6816cbe7 100644 --- a/core/translate/expr.rs +++ b/core/translate/expr.rs @@ -3392,7 +3392,22 @@ pub fn bind_and_rewrite_expr<'a>( }); if col_idx.is_some() { if match_result.is_some() { - crate::bail_parse_error!("Column {} is ambiguous", id.as_str()); + let mut ok = false; + // Column name ambiguity is ok if it is in the USING clause because then it is deduplicated + // and the left table is used. + if let Some(join_info) = &joined_table.join_info { + if join_info.using.iter().any(|using_col| { + using_col.as_str().eq_ignore_ascii_case(&normalized_id) + }) { + ok = true; + } + } + if !ok { + crate::bail_parse_error!( + "Column {} is ambiguous", + id.as_str() + ); + } } let col = joined_table.table.columns().get(col_idx.unwrap()).unwrap(); diff --git a/testing/join.test b/testing/join.test index e0fbd436d..eec61f73b 100755 --- a/testing/join.test +++ b/testing/join.test @@ -338,4 +338,16 @@ do_execsql_test_on_specific_db {:memory:} left-join-column-crash { insert into b values (3,3),(4,4); select * from a left join b on a.x < 2 where a.x < 3 and b.x < 12; } {1|1|3|3 -1|1|4|4} \ No newline at end of file +1|1|4|4} + +# Test that column names in USING clause are not ambiguous since they are deduplicated. +# The column 'a' appears in both tables but can be referenced unqualified in the SELECT +# since it's in the USING clause. +do_execsql_test_on_specific_db {:memory:} using-deduplicates-columns { + create table t(a); + create table tt(a); + insert into t values (1),(2),(3),(4),(5); + insert into tt values (4),(5),(6),(7),(8); + select a from t join tt using(a); +} {4 +5} \ No newline at end of file