mirror of
https://github.com/aljazceru/turso.git
synced 2026-01-06 01:34:21 +01:00
Merge 'translate/select: prevent multiple identical non-aliased table references ' from Preston Thorpe
closes https://github.com/tursodatabase/turso/issues/3505 Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com> Closes #3761
This commit is contained in:
@@ -986,9 +986,29 @@ fn parse_join(
|
||||
crate::bail_parse_error!("NATURAL JOIN cannot be combined with ON or USING clause");
|
||||
}
|
||||
|
||||
// this is called once for each join, so we only need to check the rightmost table
|
||||
// against all previous tables for duplicates
|
||||
let rightmost_table = table_references.joined_tables().last().unwrap();
|
||||
let has_duplicate = table_references
|
||||
.joined_tables()
|
||||
.iter()
|
||||
.take(table_references.joined_tables().len() - 1)
|
||||
.any(|t| t.identifier == rightmost_table.identifier);
|
||||
|
||||
if has_duplicate
|
||||
&& !natural
|
||||
&& constraint
|
||||
.as_ref()
|
||||
.is_none_or(|c| !matches!(c, ast::JoinConstraint::Using(_)))
|
||||
{
|
||||
// Duplicate table names are only allowed for NATURAL or USING joins
|
||||
crate::bail_parse_error!(
|
||||
"table name {} specified more than once - use an alias to disambiguate",
|
||||
rightmost_table.identifier
|
||||
);
|
||||
}
|
||||
let constraint = if natural {
|
||||
assert!(table_references.joined_tables().len() >= 2);
|
||||
let rightmost_table = table_references.joined_tables().last().unwrap();
|
||||
// NATURAL JOIN is first transformed into a USING join with the common columns
|
||||
let mut distinct_names: Vec<ast::Name> = vec![];
|
||||
// TODO: O(n^2) maybe not great for large tables or big multiway joins
|
||||
|
||||
@@ -1074,3 +1074,23 @@ do_execsql_test_on_specific_db {:memory:} rowid-select-from-clause-subquery-expl
|
||||
SELECT rowid,a FROM (SELECT rowid,a FROM t);
|
||||
} {1|abc}
|
||||
|
||||
# https://github.com/tursodatabase/turso/issues/3505 regression test
|
||||
do_execsql_test_in_memory_any_error ambiguous-self-join {
|
||||
CREATE TABLE T(a);
|
||||
INSERT INTO t VALUES (1), (2), (3);
|
||||
SELECT * fROM t JOIN t;
|
||||
}
|
||||
|
||||
do_execsql_test_on_specific_db {:memory:} unambiguous-self-join {
|
||||
CREATE TABLE T(a);
|
||||
INSERT INTO t VALUES (1), (2), (3);
|
||||
SELECT * fROM t as ta JOIN t order by ta.a;
|
||||
} {1|1
|
||||
1|2
|
||||
1|3
|
||||
2|1
|
||||
2|2
|
||||
2|3
|
||||
3|1
|
||||
3|2
|
||||
3|3}
|
||||
|
||||
Reference in New Issue
Block a user