mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-10-14 07:52:02 +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)`)
|
// appearing alone in parentheses (e.g. `FROM (mytable)`)
|
||||||
self.expected("joined table", self.peek_token())
|
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)
|
} else if dialect_of!(self is BigQueryDialect | PostgreSqlDialect | GenericDialect)
|
||||||
&& self.parse_keyword(Keyword::UNNEST)
|
&& self.parse_keyword(Keyword::UNNEST)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,9 +25,9 @@ use sqlparser::ast::SelectItem::UnnamedExpr;
|
||||||
use sqlparser::ast::TableFactor::{Pivot, Unpivot};
|
use sqlparser::ast::TableFactor::{Pivot, Unpivot};
|
||||||
use sqlparser::ast::*;
|
use sqlparser::ast::*;
|
||||||
use sqlparser::dialect::{
|
use sqlparser::dialect::{
|
||||||
AnsiDialect, BigQueryDialect, ClickHouseDialect, Dialect, DuckDbDialect, GenericDialect,
|
AnsiDialect, BigQueryDialect, ClickHouseDialect, DatabricksDialect, Dialect, DuckDbDialect,
|
||||||
HiveDialect, MsSqlDialect, MySqlDialect, PostgreSqlDialect, RedshiftSqlDialect, SQLiteDialect,
|
GenericDialect, HiveDialect, MsSqlDialect, MySqlDialect, PostgreSqlDialect, RedshiftSqlDialect,
|
||||||
SnowflakeDialect,
|
SQLiteDialect, SnowflakeDialect,
|
||||||
};
|
};
|
||||||
use sqlparser::keywords::ALL_KEYWORDS;
|
use sqlparser::keywords::ALL_KEYWORDS;
|
||||||
use sqlparser::parser::{Parser, ParserError, ParserOptions};
|
use sqlparser::parser::{Parser, ParserError, ParserOptions};
|
||||||
|
@ -9728,3 +9728,52 @@ fn parse_within_group() {
|
||||||
"OVER (PARTITION BY department)",
|
"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