diff --git a/crates/sql-parser/src/parser/errors.rs b/crates/sql-parser/src/parser/errors.rs index 9553e572a96..9a783d9a9cd 100644 --- a/crates/sql-parser/src/parser/errors.rs +++ b/crates/sql-parser/src/parser/errors.rs @@ -62,6 +62,8 @@ pub enum SqlUnsupported { MultiStatement, #[error("Multi-table DELETE is not supported")] MultiTableDelete, + #[error("Empty SQL query")] + Empty, } impl SqlUnsupported { diff --git a/crates/sql-parser/src/parser/sql.rs b/crates/sql-parser/src/parser/sql.rs index b39dc752a0f..ff8e75252d6 100644 --- a/crates/sql-parser/src/parser/sql.rs +++ b/crates/sql-parser/src/parser/sql.rs @@ -154,6 +154,9 @@ pub fn parse_sql(sql: &str) -> SqlParseResult { if stmts.len() > 1 { return Err(SqlUnsupported::MultiStatement.into()); } + if stmts.is_empty() { + return Err(SqlUnsupported::Empty.into()); + } parse_statement(stmts.swap_remove(0)) } @@ -519,6 +522,9 @@ mod tests { "select a from t where", // Empty GROUP BY "select a, count(*) from t group by", + // Empty statement + "", + " ", ] { assert!(parse_sql(sql).is_err()); } diff --git a/crates/sql-parser/src/parser/sub.rs b/crates/sql-parser/src/parser/sub.rs index d3dfd4121bd..2d925fc12b7 100644 --- a/crates/sql-parser/src/parser/sub.rs +++ b/crates/sql-parser/src/parser/sub.rs @@ -69,10 +69,11 @@ use super::{ /// Parse a SQL string pub fn parse_subscription(sql: &str) -> SqlParseResult { let mut stmts = Parser::parse_sql(&PostgreSqlDialect {}, sql)?; - if stmts.len() > 1 { - return Err(SqlUnsupported::MultiStatement.into()); + match stmts.len() { + 0 => Err(SqlUnsupported::Empty.into()), + 1 => parse_statement(stmts.swap_remove(0)), + _ => Err(SqlUnsupported::MultiStatement.into()), } - parse_statement(stmts.swap_remove(0)) } /// Parse a SQL query @@ -174,6 +175,8 @@ mod tests { fn unsupported() { for sql in [ "delete from t", + " ", + "", "select distinct a from t", "select * from (select * from t) join (select * from s) on a = b", ] {