mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-10-09 21:42:05 +00:00
fix: allow snowflake to accept values without parens (#1249)
This commit is contained in:
parent
a14faa36bb
commit
2555f713c3
2 changed files with 75 additions and 3 deletions
|
@ -8422,6 +8422,29 @@ impl<'a> Parser<'a> {
|
|||
// appearing alone in parentheses (e.g. `FROM (mytable)`)
|
||||
self.expected("joined table", self.peek_token())
|
||||
}
|
||||
} else if dialect_of!(self is SnowflakeDialect | DatabricksDialect | GenericDialect)
|
||||
&& self.parse_keyword(Keyword::VALUES)
|
||||
{
|
||||
// Snowflake and Databricks allow syntax like below:
|
||||
// SELECT * FROM VALUES (1, 'a'), (2, 'b') AS t (col1, col2)
|
||||
// where there are no parentheses around the VALUES clause.
|
||||
let values = SetExpr::Values(self.parse_values(false)?);
|
||||
let alias = self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_ALIAS)?;
|
||||
Ok(TableFactor::Derived {
|
||||
lateral: false,
|
||||
subquery: Box::new(Query {
|
||||
with: None,
|
||||
body: Box::new(values),
|
||||
order_by: vec![],
|
||||
limit: None,
|
||||
limit_by: vec![],
|
||||
offset: None,
|
||||
fetch: None,
|
||||
locks: vec![],
|
||||
for_clause: None,
|
||||
}),
|
||||
alias,
|
||||
})
|
||||
} else if dialect_of!(self is BigQueryDialect | PostgreSqlDialect | GenericDialect)
|
||||
&& self.parse_keyword(Keyword::UNNEST)
|
||||
{
|
||||
|
|
|
@ -25,9 +25,9 @@ use sqlparser::ast::SelectItem::UnnamedExpr;
|
|||
use sqlparser::ast::TableFactor::{Pivot, Unpivot};
|
||||
use sqlparser::ast::*;
|
||||
use sqlparser::dialect::{
|
||||
AnsiDialect, BigQueryDialect, ClickHouseDialect, Dialect, DuckDbDialect, GenericDialect,
|
||||
HiveDialect, MsSqlDialect, MySqlDialect, PostgreSqlDialect, RedshiftSqlDialect, SQLiteDialect,
|
||||
SnowflakeDialect,
|
||||
AnsiDialect, BigQueryDialect, ClickHouseDialect, DatabricksDialect, Dialect, DuckDbDialect,
|
||||
GenericDialect, HiveDialect, MsSqlDialect, MySqlDialect, PostgreSqlDialect, RedshiftSqlDialect,
|
||||
SQLiteDialect, SnowflakeDialect,
|
||||
};
|
||||
use sqlparser::keywords::ALL_KEYWORDS;
|
||||
use sqlparser::parser::{Parser, ParserError, ParserOptions};
|
||||
|
@ -9728,3 +9728,52 @@ fn parse_within_group() {
|
|||
"OVER (PARTITION BY department)",
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tests_select_values_without_parens() {
|
||||
let dialects = TestedDialects {
|
||||
dialects: vec![
|
||||
Box::new(GenericDialect {}),
|
||||
Box::new(SnowflakeDialect {}),
|
||||
Box::new(DatabricksDialect {}),
|
||||
],
|
||||
options: None,
|
||||
};
|
||||
let sql = "SELECT * FROM VALUES (1, 2), (2,3) AS tbl (id, val)";
|
||||
let canonical = "SELECT * FROM (VALUES (1, 2), (2, 3)) AS tbl (id, val)";
|
||||
dialects.verified_only_select_with_canonical(sql, canonical);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tests_select_values_without_parens_and_set_op() {
|
||||
let dialects = TestedDialects {
|
||||
dialects: vec![
|
||||
Box::new(GenericDialect {}),
|
||||
Box::new(SnowflakeDialect {}),
|
||||
Box::new(DatabricksDialect {}),
|
||||
],
|
||||
options: None,
|
||||
};
|
||||
let sql = "SELECT id + 1, name FROM VALUES (1, 'Apple'), (2, 'Banana'), (3, 'Orange') AS fruits (id, name) UNION ALL SELECT 5, 'Strawberry'";
|
||||
let canonical = "SELECT id + 1, name FROM (VALUES (1, 'Apple'), (2, 'Banana'), (3, 'Orange')) AS fruits (id, name) UNION ALL SELECT 5, 'Strawberry'";
|
||||
let query = dialects.verified_query_with_canonical(sql, canonical);
|
||||
match *query.body {
|
||||
SetExpr::SetOperation {
|
||||
op,
|
||||
set_quantifier: _,
|
||||
left,
|
||||
right,
|
||||
} => {
|
||||
assert_eq!(SetOperator::Union, op);
|
||||
match *left {
|
||||
SetExpr::Select(_) => {}
|
||||
_ => panic!("Expected a SELECT statement"),
|
||||
}
|
||||
match *right {
|
||||
SetExpr::Select(_) => {}
|
||||
_ => panic!("Expected a SELECT statement"),
|
||||
}
|
||||
}
|
||||
_ => panic!("Expected a SET OPERATION"),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue