Skip to content

Commit

Permalink
Don't silently accept naked OUTER JOINS
Browse files Browse the repository at this point in the history
`SELECT * FROM a OUTER JOIN b` was previously being parsed as an inner
join where table `a` was aliased to `OUTER`. This is extremely
surprising, as the user likely intended to say FULL OUTER JOIN. Since
the SQL specification lists OUTER as a keyword, we are well within our
rights to return an error here.
  • Loading branch information
benesch committed Jun 18, 2019
1 parent 7857543 commit 2c99635
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/dialect/keywords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,12 @@ pub const RESERVED_FOR_TABLE_ALIAS: &[&str] = &[
// Reserved as both a table and a column alias:
WITH, SELECT, WHERE, GROUP, HAVING, ORDER, LIMIT, OFFSET, FETCH, UNION, EXCEPT, INTERSECT,
// Reserved only as a table alias in the `FROM`/`JOIN` clauses:
ON, JOIN, INNER, CROSS, FULL, LEFT, RIGHT, NATURAL, USING,
ON, JOIN, INNER, CROSS, FULL, LEFT, RIGHT, NATURAL, USING, LIMIT, OFFSET, FETCH,
// Reserved not because of ambiguity, but so that parsing `SELECT * FROM a
// OUTER JOIN b` causes a syntax error, rather than silently parsing to an
// inner join where table `a` is aliased as `OUTER`, which is certainly not
// what the user intended and also not valid according to the SQL standard.
OUTER,
];

/// Can't be used as a column alias, so that `SELECT <expr> alias`
Expand Down
1 change: 1 addition & 0 deletions src/sqlparser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1648,6 +1648,7 @@ impl Parser {
_ => unreachable!(),
}
}
"OUTER" => return self.expected("LEFT, RIGHT, or FULL", self.peek_token()),
_ if natural => {
return self.expected("a join type after NATURAL", self.peek_token());
}
Expand Down
6 changes: 6 additions & 0 deletions tests/sqlparser_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1801,6 +1801,12 @@ fn parse_join_syntax_variants() {
"SELECT c1 FROM t1 FULL OUTER JOIN t2 USING(c1)",
"SELECT c1 FROM t1 FULL JOIN t2 USING(c1)",
);

let res = parse_sql_statements("SELECT * FROM a OUTER JOIN b ON 1");
assert_eq!(
ParserError::ParserError("Expected LEFT, RIGHT, or FULL, found: OUTER".to_string()),
res.unwrap_err()
);
}

#[test]
Expand Down

0 comments on commit 2c99635

Please sign in to comment.