Skip to content

Commit fddc88d

Browse files
committed
databricks except
1 parent a86c58b commit fddc88d

File tree

8 files changed

+63
-34
lines changed

8 files changed

+63
-34
lines changed

src/dialect/bigquery.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,9 @@ impl Dialect for BigQueryDialect {
4444
fn supports_window_clause_named_window_reference(&self) -> bool {
4545
true
4646
}
47+
48+
// See https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#select_except
49+
fn supports_select_wildcard_except(&self) -> bool {
50+
true
51+
}
4752
}

src/dialect/clickhouse.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,8 @@ impl Dialect for ClickHouseDialect {
2929
fn supports_string_literal_backslash_escape(&self) -> bool {
3030
true
3131
}
32+
33+
fn supports_select_wildcard_except(&self) -> bool {
34+
true
35+
}
3236
}

src/dialect/databricks.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,9 @@ impl Dialect for DatabricksDialect {
2929
fn supports_group_by_expr(&self) -> bool {
3030
true
3131
}
32+
33+
// https://docs.databricks.com/en/sql/language-manual/sql-ref-syntax-qry-select.html#syntax
34+
fn supports_select_wildcard_except(&self) -> bool {
35+
true
36+
}
3237
}

src/dialect/generic.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,8 @@ impl Dialect for GenericDialect {
6262
fn supports_window_clause_named_window_reference(&self) -> bool {
6363
true
6464
}
65+
66+
fn supports_select_wildcard_except(&self) -> bool {
67+
true
68+
}
6569
}

src/dialect/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,16 @@ pub trait Dialect: Debug + Any {
209209
fn supports_dictionary_syntax(&self) -> bool {
210210
false
211211
}
212+
/// Returns true if the dialect supports an `EXCEPT` clause following a
213+
/// wildcard in a select list.
214+
///
215+
/// For example
216+
/// ```sql
217+
/// SELECT * EXCEPT order_id FROM orders;
218+
/// ```
219+
fn supports_select_wildcard_except(&self) -> bool {
220+
false
221+
}
212222
/// Returns true if the dialect has a CONVERT function which accepts a type first
213223
/// and an expression second, e.g. `CONVERT(varchar, 1)`
214224
fn convert_type_before_value(&self) -> bool {

src/parser/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9513,8 +9513,7 @@ impl<'a> Parser<'a> {
95139513
} else {
95149514
None
95159515
};
9516-
let opt_except = if dialect_of!(self is GenericDialect | BigQueryDialect | ClickHouseDialect)
9517-
{
9516+
let opt_except = if self.dialect.supports_select_wildcard_except() {
95189517
self.parse_optional_select_item_except()?
95199518
} else {
95209519
None

tests/sqlparser_bigquery.rs

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,38 +1695,6 @@ fn parse_array_agg_func() {
16951695
}
16961696
}
16971697

1698-
#[test]
1699-
fn test_select_wildcard_with_except() {
1700-
let select = bigquery_and_generic().verified_only_select("SELECT * EXCEPT (col_a) FROM data");
1701-
let expected = SelectItem::Wildcard(WildcardAdditionalOptions {
1702-
opt_except: Some(ExceptSelectItem {
1703-
first_element: Ident::new("col_a"),
1704-
additional_elements: vec![],
1705-
}),
1706-
..Default::default()
1707-
});
1708-
assert_eq!(expected, select.projection[0]);
1709-
1710-
let select = bigquery_and_generic()
1711-
.verified_only_select("SELECT * EXCEPT (department_id, employee_id) FROM employee_table");
1712-
let expected = SelectItem::Wildcard(WildcardAdditionalOptions {
1713-
opt_except: Some(ExceptSelectItem {
1714-
first_element: Ident::new("department_id"),
1715-
additional_elements: vec![Ident::new("employee_id")],
1716-
}),
1717-
..Default::default()
1718-
});
1719-
assert_eq!(expected, select.projection[0]);
1720-
1721-
assert_eq!(
1722-
bigquery_and_generic()
1723-
.parse_sql_statements("SELECT * EXCEPT () FROM employee_table")
1724-
.unwrap_err()
1725-
.to_string(),
1726-
"sql parser error: Expected identifier, found: )"
1727-
);
1728-
}
1729-
17301698
#[test]
17311699
fn parse_big_query_declare() {
17321700
for (sql, expected_names, expected_data_type, expected_assigned_expr) in [

tests/sqlparser_common.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9777,3 +9777,37 @@ fn tests_select_values_without_parens_and_set_op() {
97779777
_ => panic!("Expected a SET OPERATION"),
97789778
}
97799779
}
9780+
9781+
#[test]
9782+
fn parse_select_wildcard_with_except() {
9783+
let dialects = all_dialects_where(|d| d.supports_select_wildcard_except());
9784+
9785+
let select = dialects.verified_only_select("SELECT * EXCEPT (col_a) FROM data");
9786+
let expected = SelectItem::Wildcard(WildcardAdditionalOptions {
9787+
opt_except: Some(ExceptSelectItem {
9788+
first_element: Ident::new("col_a"),
9789+
additional_elements: vec![],
9790+
}),
9791+
..Default::default()
9792+
});
9793+
assert_eq!(expected, select.projection[0]);
9794+
9795+
let select = dialects
9796+
.verified_only_select("SELECT * EXCEPT (department_id, employee_id) FROM employee_table");
9797+
let expected = SelectItem::Wildcard(WildcardAdditionalOptions {
9798+
opt_except: Some(ExceptSelectItem {
9799+
first_element: Ident::new("department_id"),
9800+
additional_elements: vec![Ident::new("employee_id")],
9801+
}),
9802+
..Default::default()
9803+
});
9804+
assert_eq!(expected, select.projection[0]);
9805+
9806+
assert_eq!(
9807+
dialects
9808+
.parse_sql_statements("SELECT * EXCEPT () FROM employee_table")
9809+
.unwrap_err()
9810+
.to_string(),
9811+
"sql parser error: Expected identifier, found: )"
9812+
);
9813+
}

0 commit comments

Comments
 (0)