Skip to content

Commit 6eeebfe

Browse files
committed
Disallow keywords as table aliases for parsing statements without semicolons
1 parent fda524c commit 6eeebfe

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

src/dialect/mod.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -958,8 +958,14 @@ pub trait Dialect: Debug + Any {
958958
/// Returns true if the specified keyword should be parsed as a table factor alias.
959959
/// When explicit is true, the keyword is preceded by an `AS` word. Parser is provided
960960
/// to enable looking ahead if needed.
961+
///
962+
/// When the dialect supports statements without semicolon delimiter, actual keywords aren't parsed as aliases.
961963
fn is_table_factor_alias(&self, explicit: bool, kw: &Keyword, _parser: &mut Parser) -> bool {
962-
explicit || !keywords::RESERVED_FOR_TABLE_ALIAS.contains(kw)
964+
if self.supports_statements_without_semicolon_delimiter() {
965+
kw == &Keyword::NoKeyword
966+
} else {
967+
explicit || !keywords::RESERVED_FOR_TABLE_ALIAS.contains(kw)
968+
}
963969
}
964970

965971
/// Returns true if this dialect supports querying historical table data

tests/sqlparser_common.rs

+37-2
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,28 @@ fn parse_select_with_table_alias() {
666666
);
667667
}
668668

669+
#[test]
670+
fn parse_select_with_table_alias_keyword() {
671+
// note: DECLARE isn't included in RESERVED_FOR_TABLE_ALIAS
672+
let table_alias_non_reserved_keyword = "SELECT a FROM lineitem DECLARE";
673+
let statements = all_dialects_requiring_semicolon_statement_delimiter()
674+
.parse_sql_statements(table_alias_non_reserved_keyword)
675+
.unwrap();
676+
assert_eq!(1, statements.len(),);
677+
assert_eq!(
678+
ParserError::ParserError("Expected: identifier, found: EOF".to_string()),
679+
all_dialects_not_requiring_semicolon_statement_delimiter()
680+
.parse_sql_statements(table_alias_non_reserved_keyword)
681+
.unwrap_err()
682+
);
683+
684+
let table_alias_quoted_keyword = "SELECT a FROM lineitem \"DECLARE\"";
685+
let statements = all_dialects()
686+
.parse_sql_statements(table_alias_quoted_keyword)
687+
.unwrap();
688+
assert_eq!(1, statements.len(),);
689+
}
690+
669691
#[test]
670692
fn parse_consecutive_queries() {
671693
let select_then_exec = "SELECT * FROM deleted; EXECUTE my_sp 'some', 'params'";
@@ -949,7 +971,18 @@ fn parse_limit() {
949971

950972
#[test]
951973
fn parse_invalid_limit_by() {
952-
assert_err_parse_statements("SELECT * FROM user BY name", "name");
974+
assert_eq!(
975+
ParserError::ParserError("Expected: end of statement, found: name".to_string()),
976+
all_dialects_requiring_semicolon_statement_delimiter()
977+
.parse_sql_statements("SELECT * FROM user BY name")
978+
.unwrap_err()
979+
);
980+
assert_eq!(
981+
ParserError::ParserError("Expected: an SQL statement, found: BY".to_string()),
982+
all_dialects_not_requiring_semicolon_statement_delimiter()
983+
.parse_sql_statements("SELECT * FROM user BY name")
984+
.unwrap_err()
985+
);
953986
}
954987

955988
#[test]
@@ -10826,7 +10859,9 @@ fn parse_select_table_with_index_hints() {
1082610859

1082710860
// Test that dialects that don't support table hints will keep parsing the USE as table alias
1082810861
let sql = "SELECT * FROM T USE LIMIT 1";
10829-
let unsupported_dialects = all_dialects_where(|d| !d.supports_table_hints());
10862+
let unsupported_dialects = all_dialects_where(|d| {
10863+
!d.supports_table_hints() && !d.supports_statements_without_semicolon_delimiter()
10864+
});
1083010865
let select = unsupported_dialects
1083110866
.verified_only_select_with_canonical(sql, "SELECT * FROM T AS USE LIMIT 1");
1083210867
assert_eq!(

0 commit comments

Comments
 (0)