Skip to content

Commit 5ed13b5

Browse files
authored
Databricks: support SELECT * EXCEPT (apache#1261)
1 parent 49d1784 commit 5ed13b5

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
@@ -54,4 +54,9 @@ impl Dialect for BigQueryDialect {
5454
fn supports_parenthesized_set_variables(&self) -> bool {
5555
true
5656
}
57+
58+
// See https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#select_except
59+
fn supports_select_wildcard_except(&self) -> bool {
60+
true
61+
}
5762
}

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
@@ -33,4 +33,9 @@ impl Dialect for DatabricksDialect {
3333
fn supports_lambda_functions(&self) -> bool {
3434
true
3535
}
36+
37+
// https://docs.databricks.com/en/sql/language-manual/sql-ref-syntax-qry-select.html#syntax
38+
fn supports_select_wildcard_except(&self) -> bool {
39+
true
40+
}
3641
}

src/dialect/generic.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,8 @@ impl Dialect for GenericDialect {
6666
fn supports_parenthesized_set_variables(&self) -> bool {
6767
true
6868
}
69+
70+
fn supports_select_wildcard_except(&self) -> bool {
71+
true
72+
}
6973
}

src/dialect/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,16 @@ pub trait Dialect: Debug + Any {
226226
fn supports_parenthesized_set_variables(&self) -> bool {
227227
false
228228
}
229+
/// Returns true if the dialect supports an `EXCEPT` clause following a
230+
/// wildcard in a select list.
231+
///
232+
/// For example
233+
/// ```sql
234+
/// SELECT * EXCEPT order_id FROM orders;
235+
/// ```
236+
fn supports_select_wildcard_except(&self) -> bool {
237+
false
238+
}
229239
/// Returns true if the dialect has a CONVERT function which accepts a type first
230240
/// and an expression second, e.g. `CONVERT(varchar, 1)`
231241
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
@@ -9704,8 +9704,7 @@ impl<'a> Parser<'a> {
97049704
} else {
97059705
None
97069706
};
9707-
let opt_except = if dialect_of!(self is GenericDialect | BigQueryDialect | ClickHouseDialect)
9708-
{
9707+
let opt_except = if self.dialect.supports_select_wildcard_except() {
97099708
self.parse_optional_select_item_except()?
97109709
} else {
97119710
None

tests/sqlparser_bigquery.rs

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1838,38 +1838,6 @@ fn parse_array_agg_func() {
18381838
}
18391839
}
18401840

1841-
#[test]
1842-
fn test_select_wildcard_with_except() {
1843-
let select = bigquery_and_generic().verified_only_select("SELECT * EXCEPT (col_a) FROM data");
1844-
let expected = SelectItem::Wildcard(WildcardAdditionalOptions {
1845-
opt_except: Some(ExceptSelectItem {
1846-
first_element: Ident::new("col_a"),
1847-
additional_elements: vec![],
1848-
}),
1849-
..Default::default()
1850-
});
1851-
assert_eq!(expected, select.projection[0]);
1852-
1853-
let select = bigquery_and_generic()
1854-
.verified_only_select("SELECT * EXCEPT (department_id, employee_id) FROM employee_table");
1855-
let expected = SelectItem::Wildcard(WildcardAdditionalOptions {
1856-
opt_except: Some(ExceptSelectItem {
1857-
first_element: Ident::new("department_id"),
1858-
additional_elements: vec![Ident::new("employee_id")],
1859-
}),
1860-
..Default::default()
1861-
});
1862-
assert_eq!(expected, select.projection[0]);
1863-
1864-
assert_eq!(
1865-
bigquery_and_generic()
1866-
.parse_sql_statements("SELECT * EXCEPT () FROM employee_table")
1867-
.unwrap_err()
1868-
.to_string(),
1869-
"sql parser error: Expected identifier, found: )"
1870-
);
1871-
}
1872-
18731841
#[test]
18741842
fn parse_big_query_declare() {
18751843
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
@@ -9854,3 +9854,37 @@ fn tests_select_values_without_parens_and_set_op() {
98549854
_ => panic!("Expected a SET OPERATION"),
98559855
}
98569856
}
9857+
9858+
#[test]
9859+
fn parse_select_wildcard_with_except() {
9860+
let dialects = all_dialects_where(|d| d.supports_select_wildcard_except());
9861+
9862+
let select = dialects.verified_only_select("SELECT * EXCEPT (col_a) FROM data");
9863+
let expected = SelectItem::Wildcard(WildcardAdditionalOptions {
9864+
opt_except: Some(ExceptSelectItem {
9865+
first_element: Ident::new("col_a"),
9866+
additional_elements: vec![],
9867+
}),
9868+
..Default::default()
9869+
});
9870+
assert_eq!(expected, select.projection[0]);
9871+
9872+
let select = dialects
9873+
.verified_only_select("SELECT * EXCEPT (department_id, employee_id) FROM employee_table");
9874+
let expected = SelectItem::Wildcard(WildcardAdditionalOptions {
9875+
opt_except: Some(ExceptSelectItem {
9876+
first_element: Ident::new("department_id"),
9877+
additional_elements: vec![Ident::new("employee_id")],
9878+
}),
9879+
..Default::default()
9880+
});
9881+
assert_eq!(expected, select.projection[0]);
9882+
9883+
assert_eq!(
9884+
dialects
9885+
.parse_sql_statements("SELECT * EXCEPT () FROM employee_table")
9886+
.unwrap_err()
9887+
.to_string(),
9888+
"sql parser error: Expected identifier, found: )"
9889+
);
9890+
}

0 commit comments

Comments
 (0)