Skip to content

Commit 485b511

Browse files
committed
Modify the code according to the recommendations and add more test cases
1 parent e6c96b9 commit 485b511

File tree

5 files changed

+98
-37
lines changed

5 files changed

+98
-37
lines changed

src/dialect/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,16 @@ pub trait Dialect: Debug + Any {
590590
fn supports_try_convert(&self) -> bool {
591591
false
592592
}
593+
594+
/// Returns true if the dialect supports `listen` clause
595+
fn supports_listen_clause(&self) -> bool {
596+
false
597+
}
598+
599+
/// Returns true if the dialect supports `notify` clause
600+
fn supports_notify_clause(&self) -> bool {
601+
false
602+
}
593603
}
594604

595605
/// This represents the operators for which precedence must be defined

src/dialect/postgresql.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,16 @@ impl Dialect for PostgreSqlDialect {
191191
fn supports_explain_with_utility_options(&self) -> bool {
192192
true
193193
}
194+
195+
/// see <https://www.postgresql.org/docs/current/sql-listen.html>
196+
fn supports_listen_clause(&self) -> bool {
197+
true
198+
}
199+
200+
/// see <https://www.postgresql.org/docs/current/sql-notify.html>
201+
fn supports_notify_clause(&self) -> bool {
202+
true
203+
}
194204
}
195205

196206
pub fn parse_comment(parser: &mut Parser) -> Result<Statement, ParserError> {

src/parser/mod.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -534,12 +534,8 @@ impl<'a> Parser<'a> {
534534
Keyword::MERGE => self.parse_merge(),
535535
// `LISTEN` and `NOTIFY` are Postgres-specific
536536
// syntaxes. They are used for Postgres statement.
537-
Keyword::LISTEN if dialect_of!(self is PostgreSqlDialect | GenericDialect) => {
538-
self.parse_listen()
539-
}
540-
Keyword::NOTIFY if dialect_of!(self is PostgreSqlDialect | GenericDialect) => {
541-
self.parse_notify()
542-
}
537+
Keyword::LISTEN if self.dialect.supports_listen_clause() => self.parse_listen(),
538+
Keyword::NOTIFY if self.dialect.supports_notify_clause() => self.parse_notify(),
543539
// `PRAGMA` is sqlite specific https://www.sqlite.org/pragma.html
544540
Keyword::PRAGMA => self.parse_pragma(),
545541
Keyword::UNLOAD => self.parse_unload(),

tests/sqlparser_common.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11460,3 +11460,79 @@ fn test_try_convert() {
1146011460
all_dialects_where(|d| d.supports_try_convert() && !d.convert_type_before_value());
1146111461
dialects.verified_expr("TRY_CONVERT('foo', VARCHAR(MAX))");
1146211462
}
11463+
11464+
#[test]
11465+
fn parse_listen_channel() {
11466+
let dialects = all_dialects_where(|d| d.supports_listen_clause());
11467+
11468+
match dialects.verified_stmt("LISTEN test1") {
11469+
Statement::LISTEN { channel } => {
11470+
assert_eq!(Ident::new("test1"), channel);
11471+
}
11472+
_ => unreachable!(),
11473+
};
11474+
11475+
assert_eq!(
11476+
dialects.parse_sql_statements("LISTEN *").unwrap_err(),
11477+
ParserError::ParserError("Expected: identifier, found: *".to_string())
11478+
);
11479+
11480+
let dialects = all_dialects_where(|d| !d.supports_listen_clause());
11481+
11482+
assert_eq!(
11483+
dialects.parse_sql_statements("LISTEN test1").unwrap_err(),
11484+
ParserError::ParserError("Expected: an SQL statement, found: LISTEN".to_string())
11485+
);
11486+
}
11487+
11488+
#[test]
11489+
fn parse_notify_channel() {
11490+
let dialects = all_dialects_where(|d| d.supports_notify_clause());
11491+
11492+
match dialects.verified_stmt("NOTIFY test1") {
11493+
Statement::NOTIFY { channel, payload } => {
11494+
assert_eq!(Ident::new("test1"), channel);
11495+
assert_eq!(payload, None);
11496+
}
11497+
_ => unreachable!(),
11498+
};
11499+
11500+
match dialects.verified_stmt("NOTIFY test1, 'this is a test notification'") {
11501+
Statement::NOTIFY {
11502+
channel,
11503+
payload: Some(payload),
11504+
} => {
11505+
assert_eq!(Ident::new("test1"), channel);
11506+
assert_eq!("this is a test notification", payload);
11507+
}
11508+
_ => unreachable!(),
11509+
};
11510+
11511+
assert_eq!(
11512+
dialects.parse_sql_statements("NOTIFY *").unwrap_err(),
11513+
ParserError::ParserError("Expected: identifier, found: *".to_string())
11514+
);
11515+
assert_eq!(
11516+
dialects
11517+
.parse_sql_statements("NOTIFY test1, *")
11518+
.unwrap_err(),
11519+
ParserError::ParserError("Expected: literal string, found: *".to_string())
11520+
);
11521+
11522+
let sql_statements = [
11523+
"NOTIFY test1",
11524+
"NOTIFY test1, 'this is a test notification'",
11525+
];
11526+
let dialects = all_dialects_where(|d| !d.supports_notify_clause());
11527+
11528+
for &sql in &sql_statements {
11529+
assert_eq!(
11530+
dialects.parse_sql_statements(sql).unwrap_err(),
11531+
ParserError::ParserError("Expected: an SQL statement, found: NOTIFY".to_string())
11532+
);
11533+
assert_eq!(
11534+
dialects.parse_sql_statements(sql).unwrap_err(),
11535+
ParserError::ParserError("Expected: an SQL statement, found: NOTIFY".to_string())
11536+
);
11537+
}
11538+
}

tests/sqlparser_postgres.rs

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5157,34 +5157,3 @@ fn parse_create_type_as_enum() {
51575157
_ => unreachable!(),
51585158
}
51595159
}
5160-
5161-
#[test]
5162-
fn parse_listen_channel() {
5163-
match pg_and_generic().verified_stmt("LISTEN test1") {
5164-
Statement::LISTEN { channel } => {
5165-
assert_eq!(Ident::new("test1"), channel);
5166-
}
5167-
_ => unreachable!(),
5168-
}
5169-
}
5170-
5171-
#[test]
5172-
fn parse_notify_channel() {
5173-
match pg_and_generic().verified_stmt("NOTIFY test1") {
5174-
Statement::NOTIFY { channel, payload } => {
5175-
assert_eq!(Ident::new("test1"), channel);
5176-
assert_eq!(payload, None);
5177-
}
5178-
_ => unreachable!(),
5179-
}
5180-
match pg_and_generic().verified_stmt("NOTIFY test1, 'this is a test notification'") {
5181-
Statement::NOTIFY {
5182-
channel,
5183-
payload: Some(payload),
5184-
} => {
5185-
assert_eq!(Ident::new("test1"), channel);
5186-
assert_eq!("this is a test notification", payload);
5187-
}
5188-
_ => unreachable!(),
5189-
}
5190-
}

0 commit comments

Comments
 (0)