Skip to content

Commit 0330f9d

Browse files
alexander-beedieAlexander Beediejmhain
authored
Support use of BY NAME quantifier across all set ops (#1309)
Co-authored-by: Alexander Beedie <[email protected]> Co-authored-by: Joey Hain <[email protected]>
1 parent deac269 commit 0330f9d

File tree

6 files changed

+18
-21
lines changed

6 files changed

+18
-21
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,13 +114,12 @@ $ cargo run --features json_example --example cli FILENAME.sql [--dialectname]
114114

115115
## Users
116116

117-
This parser is currently being used by the [DataFusion] query engine,
118-
[LocustDB], [Ballista], [GlueSQL], [Opteryx], [PRQL], [Qrlew], [JumpWire], and [ParadeDB].
117+
This parser is currently being used by the [DataFusion] query engine, [LocustDB],
118+
[Ballista], [GlueSQL], [Opteryx], [Polars], [PRQL], [Qrlew], [JumpWire], and [ParadeDB].
119119

120120
If your project is using sqlparser-rs feel free to make a PR to add it
121121
to this list.
122122

123-
124123
## Design
125124

126125
The core expression parser uses the [Pratt Parser] design, which is a top-down
@@ -210,6 +209,7 @@ licensed as above, without any additional terms or conditions.
210209
[Ballista]: https://github.com/apache/arrow-ballista
211210
[GlueSQL]: https://github.com/gluesql/gluesql
212211
[Opteryx]: https://github.com/mabel-dev/opteryx
212+
[Polars]: https://pola.rs/
213213
[PRQL]: https://github.com/PRQL/prql
214214
[Qrlew]: https://github.com/Qrlew/qrlew
215215
[JumpWire]: https://github.com/extragoodlabs/jumpwire

src/ast/data_type.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ pub enum DataType {
168168
UnsignedInt(Option<u64>),
169169
/// Unsigned int4 with optional display width e.g. INT4 UNSIGNED or INT4(11) UNSIGNED
170170
UnsignedInt4(Option<u64>),
171-
/// Unsigned integer with optional display width e.g. INTGER UNSIGNED or INTEGER(11) UNSIGNED
171+
/// Unsigned integer with optional display width e.g. INTEGER UNSIGNED or INTEGER(11) UNSIGNED
172172
UnsignedInteger(Option<u64>),
173173
/// Unsigned integer type in [clickhouse]
174174
/// Note: UInt8 mean 8 bits in [clickhouse]
@@ -699,7 +699,7 @@ pub enum CharacterLength {
699699
/// Optional unit. If not informed, the ANSI handles it as CHARACTERS implicitly
700700
unit: Option<CharLengthUnits>,
701701
},
702-
/// VARCHAR(MAX) or NVARCHAR(MAX), used in T-SQL (Miscrosoft SQL Server)
702+
/// VARCHAR(MAX) or NVARCHAR(MAX), used in T-SQL (Microsoft SQL Server)
703703
Max,
704704
}
705705

src/ast/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2265,7 +2265,7 @@ pub enum Statement {
22652265
/// SET [ SESSION | LOCAL ] ROLE role_name
22662266
/// ```
22672267
///
2268-
/// Sets sesssion state. Examples: [ANSI][1], [Postgresql][2], [MySQL][3], and [Oracle][4]
2268+
/// Sets session state. Examples: [ANSI][1], [Postgresql][2], [MySQL][3], and [Oracle][4]
22692269
///
22702270
/// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#set-role-statement
22712271
/// [2]: https://www.postgresql.org/docs/14/sql-set-role.html
@@ -2283,7 +2283,7 @@ pub enum Statement {
22832283
/// ```
22842284
///
22852285
/// Note: this is not a standard SQL statement, but it is supported by at
2286-
/// least MySQL and PostgreSQL. Not all MySQL-specific syntatic forms are
2286+
/// least MySQL and PostgreSQL. Not all MySQL-specific syntactic forms are
22872287
/// supported yet.
22882288
SetVariable {
22892289
local: bool,
@@ -4750,7 +4750,7 @@ impl fmt::Display for FunctionArguments {
47504750
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
47514751
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
47524752
pub struct FunctionArgumentList {
4753-
/// `[ ALL | DISTINCT ]
4753+
/// `[ ALL | DISTINCT ]`
47544754
pub duplicate_treatment: Option<DuplicateTreatment>,
47554755
/// The function arguments.
47564756
pub args: Vec<FunctionArg>,

src/parser/mod.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8138,7 +8138,7 @@ impl<'a> Parser<'a> {
81388138

81398139
pub fn parse_set_quantifier(&mut self, op: &Option<SetOperator>) -> SetQuantifier {
81408140
match op {
8141-
Some(SetOperator::Union) => {
8141+
Some(SetOperator::Except | SetOperator::Intersect | SetOperator::Union) => {
81428142
if self.parse_keywords(&[Keyword::DISTINCT, Keyword::BY, Keyword::NAME]) {
81438143
SetQuantifier::DistinctByName
81448144
} else if self.parse_keywords(&[Keyword::BY, Keyword::NAME]) {
@@ -8155,15 +8155,6 @@ impl<'a> Parser<'a> {
81558155
SetQuantifier::None
81568156
}
81578157
}
8158-
Some(SetOperator::Except) | Some(SetOperator::Intersect) => {
8159-
if self.parse_keyword(Keyword::ALL) {
8160-
SetQuantifier::All
8161-
} else if self.parse_keyword(Keyword::DISTINCT) {
8162-
SetQuantifier::Distinct
8163-
} else {
8164-
SetQuantifier::None
8165-
}
8166-
}
81678158
_ => SetQuantifier::None,
81688159
}
81698160
}
@@ -8547,10 +8538,10 @@ impl<'a> Parser<'a> {
85478538
})
85488539
} else if variable.to_string() == "TRANSACTION" && modifier.is_none() {
85498540
if self.parse_keyword(Keyword::SNAPSHOT) {
8550-
let snaphot_id = self.parse_value()?;
8541+
let snapshot_id = self.parse_value()?;
85518542
return Ok(Statement::SetTransaction {
85528543
modes: vec![],
8553-
snapshot: Some(snaphot_id),
8544+
snapshot: Some(snapshot_id),
85548545
session: false,
85558546
});
85568547
}

src/tokenizer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,7 @@ impl<'a> Tokenizer<'a> {
654654
Ok(())
655655
}
656656

657-
// Tokenize the identifer or keywords in `ch`
657+
// Tokenize the identifier or keywords in `ch`
658658
fn tokenize_identifier_or_keyword(
659659
&self,
660660
ch: impl IntoIterator<Item = char>,

tests/sqlparser_common.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6010,6 +6010,12 @@ fn parse_union_except_intersect() {
60106010
verified_stmt("SELECT foo FROM tab UNION SELECT bar FROM TAB");
60116011
verified_stmt("(SELECT * FROM new EXCEPT SELECT * FROM old) UNION ALL (SELECT * FROM old EXCEPT SELECT * FROM new) ORDER BY 1");
60126012
verified_stmt("(SELECT * FROM new EXCEPT DISTINCT SELECT * FROM old) UNION DISTINCT (SELECT * FROM old EXCEPT DISTINCT SELECT * FROM new) ORDER BY 1");
6013+
verified_stmt("SELECT 1 AS x, 2 AS y EXCEPT BY NAME SELECT 9 AS y, 8 AS x");
6014+
verified_stmt("SELECT 1 AS x, 2 AS y EXCEPT ALL BY NAME SELECT 9 AS y, 8 AS x");
6015+
verified_stmt("SELECT 1 AS x, 2 AS y EXCEPT DISTINCT BY NAME SELECT 9 AS y, 8 AS x");
6016+
verified_stmt("SELECT 1 AS x, 2 AS y INTERSECT BY NAME SELECT 9 AS y, 8 AS x");
6017+
verified_stmt("SELECT 1 AS x, 2 AS y INTERSECT ALL BY NAME SELECT 9 AS y, 8 AS x");
6018+
verified_stmt("SELECT 1 AS x, 2 AS y INTERSECT DISTINCT BY NAME SELECT 9 AS y, 8 AS x");
60136019
}
60146020

60156021
#[test]

0 commit comments

Comments
 (0)