Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/dialect/hive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,11 @@ impl Dialect for HiveDialect {
fn supports_group_by_with_modifier(&self) -> bool {
true
}

// TODO: The parsing of the FROM keyword seems wrong, as it happens within the CTE.
// See https://github.com/apache/datafusion-sqlparser-rs/issues/2236 for more details.
/// See <https://hive.apache.org/docs/latest/language/common-table-expression/>
fn supports_from_first_insert(&self) -> bool {
true
}
}
15 changes: 15 additions & 0 deletions src/dialect/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,21 @@ pub trait Dialect: Debug + Any {
false
}

/// Return true if the dialect supports "FROM-first" inserts.
///
/// Example:
/// ```sql
/// WITH cte AS (SELECT key FROM src)
/// FROM cte
/// INSERT OVERWRITE table my_table
/// SELECT *
///
/// See <https://hive.apache.org/docs/latest/language/common-table-expression/>
/// ```
fn supports_from_first_insert(&self) -> bool {
false
}

/// Return true if the dialect supports pipe operator.
///
/// Example:
Expand Down
2 changes: 1 addition & 1 deletion src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13958,7 +13958,7 @@ impl<'a> Parser<'a> {
closing_paren_token: closing_paren_token.into(),
}
};
if self.parse_keyword(Keyword::FROM) {
if self.dialect.supports_from_first_insert() && self.parse_keyword(Keyword::FROM) {
cte.from = Some(self.parse_identifier()?);
}
Ok(cte)
Expand Down
29 changes: 28 additions & 1 deletion tests/sqlparser_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16069,10 +16069,37 @@ fn test_select_from_first() {
pipe_operators: vec![],
};
assert_eq!(expected, ast);
assert_eq!(ast.to_string(), q);
}
}

#[test]
fn test_select_from_first_with_cte() {
let dialects = all_dialects_where(|d| d.supports_from_first_select());
let q = "WITH test AS (FROM t SELECT a) FROM test SELECT 1";

let ast = dialects.verified_query(q);

let ast_select = ast.body.as_select().unwrap();

let expected_body_select_projection =
vec![SelectItem::UnnamedExpr(Expr::Value(ValueWithSpan {
value: test_utils::number("1"),
span: Span::empty(),
}))];

let expected_body_from = vec![TableWithJoins {
relation: table_from_name(ObjectName::from(vec![Ident {
value: "test".to_string(),
quote_style: None,
span: Span::empty(),
}])),
joins: vec![],
}];

assert_eq!(ast_select.projection, expected_body_select_projection);
assert_eq!(ast_select.from, expected_body_from);
}

#[test]
fn test_geometric_unary_operators() {
// Number of points in path or polygon
Expand Down
Loading