Skip to content

Commit 699fddd

Browse files
authored
Merge branch 'sqlparser-rs:main' into main
2 parents cdd2ce1 + 9c87d3b commit 699fddd

File tree

6 files changed

+58
-9
lines changed

6 files changed

+58
-9
lines changed

CHANGELOG.md

+9
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@ Given that the parser produces a typed AST, any changes to the AST will technica
88
## [Unreleased]
99
Check https://github.com/sqlparser-rs/sqlparser-rs/commits/main for undocumented changes.
1010

11+
## [0.12.0] 2020-10-14
12+
13+
### Added
14+
* Add support for [NOT] IS DISTINCT FROM (#306) - @Dandandan
15+
16+
### Changed
17+
* Move the keywords module - Thanks @koushiro!
18+
19+
1120
## [0.11.0] 2020-09-24
1221

1322
### Added

docs/releasing.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ $ cargo install cargo-release
3131
$ cargo release minor --push-remote upstream
3232
```
3333
34-
You can add `--dry-run` to see what the command is going to do,
35-
or `--skip-push` to stop before actually publishing the release.
34+
After verifying, you can rerun with `--execute` if all looks good.
35+
You can add `--no-push` to stop before actually publishing the release.
3636
3737
`cargo release` will then:
3838

src/ast/mod.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,14 @@ pub enum Expr {
169169
QualifiedWildcard(Vec<Ident>),
170170
/// Multi-part identifier, e.g. `table_alias.column` or `schema.table.col`
171171
CompoundIdentifier(Vec<Ident>),
172-
/// `IS NULL` expression
172+
/// `IS NULL` operator
173173
IsNull(Box<Expr>),
174-
/// `IS NOT NULL` expression
174+
/// `IS NOT NULL` operator
175175
IsNotNull(Box<Expr>),
176+
/// `IS DISTINCT FROM` operator
177+
IsDistinctFrom(Box<Expr>, Box<Expr>),
178+
/// `IS NOT DISTINCT FROM` operator
179+
IsNotDistinctFrom(Box<Expr>, Box<Expr>),
176180
/// `[ NOT ] IN (val1, val2, ...)`
177181
InList {
178182
expr: Box<Expr>,
@@ -387,6 +391,8 @@ impl fmt::Display for Expr {
387391

388392
write!(f, ")")
389393
}
394+
Expr::IsDistinctFrom(a, b) => write!(f, "{} IS DISTINCT FROM {}", a, b),
395+
Expr::IsNotDistinctFrom(a, b) => write!(f, "{} IS NOT DISTINCT FROM {}", a, b),
390396
Expr::Trim { expr, trim_where } => {
391397
write!(f, "TRIM(")?;
392398
if let Some((ident, trim_char)) = trim_where {

src/dialect/mod.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,8 @@ mod tests {
8787

8888
assert!(dialect_of!(generic_holder is GenericDialect | AnsiDialect),);
8989
assert!(!dialect_of!(generic_holder is AnsiDialect));
90-
91-
assert!(dialect_of!(ansi_holder is AnsiDialect));
92-
assert!(dialect_of!(ansi_holder is GenericDialect | AnsiDialect),);
93-
assert!(!dialect_of!(ansi_holder is GenericDialect | MsSqlDialect),);
90+
assert!(dialect_of!(ansi_holder is AnsiDialect));
91+
assert!(dialect_of!(ansi_holder is GenericDialect | AnsiDialect));
92+
assert!(!dialect_of!(ansi_holder is GenericDialect | MsSqlDialect));
9493
}
9594
}

src/parser.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -935,8 +935,18 @@ impl<'a> Parser<'a> {
935935
Ok(Expr::IsNull(Box::new(expr)))
936936
} else if self.parse_keywords(&[Keyword::NOT, Keyword::NULL]) {
937937
Ok(Expr::IsNotNull(Box::new(expr)))
938+
} else if self.parse_keywords(&[Keyword::DISTINCT, Keyword::FROM]) {
939+
let expr2 = self.parse_expr()?;
940+
Ok(Expr::IsDistinctFrom(Box::new(expr), Box::new(expr2)))
941+
} else if self.parse_keywords(&[Keyword::NOT, Keyword::DISTINCT, Keyword::FROM])
942+
{
943+
let expr2 = self.parse_expr()?;
944+
Ok(Expr::IsNotDistinctFrom(Box::new(expr), Box::new(expr2)))
938945
} else {
939-
self.expected("NULL or NOT NULL after IS", self.peek_token())
946+
self.expected(
947+
"[NOT] NULL or [NOT] DISTINCT FROM after IS",
948+
self.peek_token(),
949+
)
940950
}
941951
}
942952
Keyword::NOT | Keyword::IN | Keyword::BETWEEN => {

tests/sqlparser_common.rs

+25
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,31 @@ fn parse_is_not_null() {
642642
);
643643
}
644644

645+
#[test]
646+
fn parse_is_distinct_from() {
647+
use self::Expr::*;
648+
let sql = "a IS DISTINCT FROM b";
649+
assert_eq!(
650+
IsDistinctFrom(
651+
Box::new(Identifier(Ident::new("a"))),
652+
Box::new(Identifier(Ident::new("b")))
653+
),
654+
verified_expr(sql)
655+
);
656+
}
657+
#[test]
658+
fn parse_is_not_distinct_from() {
659+
use self::Expr::*;
660+
let sql = "a IS NOT DISTINCT FROM b";
661+
assert_eq!(
662+
IsNotDistinctFrom(
663+
Box::new(Identifier(Ident::new("a"))),
664+
Box::new(Identifier(Ident::new("b")))
665+
),
666+
verified_expr(sql)
667+
);
668+
}
669+
645670
#[test]
646671
fn parse_not_precedence() {
647672
// NOT has higher precedence than OR/AND, so the following must parse as (NOT true) OR true

0 commit comments

Comments
 (0)