Skip to content

Commit 69162d9

Browse files
fix: allow snowflake/ databricks to accept values without parens (#24)
I took a crack at https://sigmacomputing.slack.com/archives/C045CUB1CUQ/p1714699037650289. As far as I can tell Snowflake is the only dialect that supports this (from googling)... but I don't know how to check unless I run a query in each DB? Do we have a way to do that?
2 parents fd6ad77 + ffc6c0d commit 69162d9

2 files changed

Lines changed: 75 additions & 3 deletions

File tree

src/parser/mod.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8355,6 +8355,29 @@ impl<'a> Parser<'a> {
83558355
// appearing alone in parentheses (e.g. `FROM (mytable)`)
83568356
self.expected("joined table", self.peek_token())
83578357
}
8358+
} else if dialect_of!(self is SnowflakeDialect | DatabricksDialect | GenericDialect)
8359+
&& self.parse_keyword(Keyword::VALUES)
8360+
{
8361+
// Snowflake and Databricks allow syntax like below:
8362+
// SELECT * FROM VALUES (1, 'a'), (2, 'b') AS t (col1, col2)
8363+
// where there are no parentheses around the VALUES clause.
8364+
let values = SetExpr::Values(self.parse_values(false)?);
8365+
let alias = self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_ALIAS)?;
8366+
Ok(TableFactor::Derived {
8367+
lateral: false,
8368+
subquery: Box::new(Query {
8369+
with: None,
8370+
body: Box::new(values),
8371+
order_by: vec![],
8372+
limit: None,
8373+
limit_by: vec![],
8374+
offset: None,
8375+
fetch: None,
8376+
locks: vec![],
8377+
for_clause: None,
8378+
}),
8379+
alias,
8380+
})
83588381
} else if dialect_of!(self is BigQueryDialect | PostgreSqlDialect | GenericDialect)
83598382
&& self.parse_keyword(Keyword::UNNEST)
83608383
{

tests/sqlparser_common.rs

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ use sqlparser::ast::SelectItem::UnnamedExpr;
2525
use sqlparser::ast::TableFactor::{Pivot, Unpivot};
2626
use sqlparser::ast::*;
2727
use sqlparser::dialect::{
28-
AnsiDialect, BigQueryDialect, ClickHouseDialect, Dialect, DuckDbDialect, GenericDialect,
29-
HiveDialect, MsSqlDialect, MySqlDialect, PostgreSqlDialect, RedshiftSqlDialect, SQLiteDialect,
30-
SnowflakeDialect,
28+
AnsiDialect, BigQueryDialect, ClickHouseDialect, DatabricksDialect, Dialect, DuckDbDialect,
29+
GenericDialect, HiveDialect, MsSqlDialect, MySqlDialect, PostgreSqlDialect, RedshiftSqlDialect,
30+
SQLiteDialect, SnowflakeDialect,
3131
};
3232
use sqlparser::keywords::ALL_KEYWORDS;
3333
use sqlparser::parser::{Parser, ParserError, ParserOptions};
@@ -9658,3 +9658,52 @@ fn test_dictionary_syntax() {
96589658
]),
96599659
)
96609660
}
9661+
9662+
#[test]
9663+
fn tests_select_values_without_parens() {
9664+
let dialects = TestedDialects {
9665+
dialects: vec![
9666+
Box::new(GenericDialect {}),
9667+
Box::new(SnowflakeDialect {}),
9668+
Box::new(DatabricksDialect {}),
9669+
],
9670+
options: None,
9671+
};
9672+
let sql = "SELECT * FROM VALUES (1, 2), (2,3) AS tbl (id, val)";
9673+
let canonical = "SELECT * FROM (VALUES (1, 2), (2, 3)) AS tbl (id, val)";
9674+
dialects.verified_only_select_with_canonical(sql, canonical);
9675+
}
9676+
9677+
#[test]
9678+
fn tests_select_values_without_parens_and_set_op() {
9679+
let dialects = TestedDialects {
9680+
dialects: vec![
9681+
Box::new(GenericDialect {}),
9682+
Box::new(SnowflakeDialect {}),
9683+
Box::new(DatabricksDialect {}),
9684+
],
9685+
options: None,
9686+
};
9687+
let sql = "SELECT id + 1, name FROM VALUES (1, 'Apple'), (2, 'Banana'), (3, 'Orange') AS fruits (id, name) UNION ALL SELECT 5, 'Strawberry'";
9688+
let canonical = "SELECT id + 1, name FROM (VALUES (1, 'Apple'), (2, 'Banana'), (3, 'Orange')) AS fruits (id, name) UNION ALL SELECT 5, 'Strawberry'";
9689+
let query = dialects.verified_query_with_canonical(sql, canonical);
9690+
match *query.body {
9691+
SetExpr::SetOperation {
9692+
op,
9693+
set_quantifier: _,
9694+
left,
9695+
right,
9696+
} => {
9697+
assert_eq!(SetOperator::Union, op);
9698+
match *left {
9699+
SetExpr::Select(_) => {}
9700+
_ => panic!("Expected a SELECT statement"),
9701+
}
9702+
match *right {
9703+
SetExpr::Select(_) => {}
9704+
_ => panic!("Expected a SELECT statement"),
9705+
}
9706+
}
9707+
_ => panic!("Expected a SET OPERATION"),
9708+
}
9709+
}

0 commit comments

Comments
 (0)