mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-11-17 05:48:35 +00:00
Add support for INSERT INTO VALUE (#2085)
Some checks are pending
license / Release Audit Tool (RAT) (push) Waiting to run
Rust / codestyle (push) Waiting to run
Rust / lint (push) Waiting to run
Rust / benchmark-lint (push) Waiting to run
Rust / compile (push) Waiting to run
Rust / docs (push) Waiting to run
Rust / compile-no-std (push) Waiting to run
Rust / test (beta) (push) Waiting to run
Rust / test (nightly) (push) Waiting to run
Rust / test (stable) (push) Waiting to run
Some checks are pending
license / Release Audit Tool (RAT) (push) Waiting to run
Rust / codestyle (push) Waiting to run
Rust / lint (push) Waiting to run
Rust / benchmark-lint (push) Waiting to run
Rust / compile (push) Waiting to run
Rust / docs (push) Waiting to run
Rust / compile-no-std (push) Waiting to run
Rust / test (beta) (push) Waiting to run
Rust / test (nightly) (push) Waiting to run
Rust / test (stable) (push) Waiting to run
This commit is contained in:
parent
c439ee9419
commit
f69407b344
8 changed files with 64 additions and 13 deletions
|
|
@ -3135,12 +3135,18 @@ pub struct Values {
|
|||
/// Was there an explicit ROWs keyword (MySQL)?
|
||||
/// <https://dev.mysql.com/doc/refman/8.0/en/values.html>
|
||||
pub explicit_row: bool,
|
||||
// MySql supports both VALUES and VALUE keywords.
|
||||
// <https://dev.mysql.com/doc/refman/9.2/en/insert.html>
|
||||
pub value_keyword: bool,
|
||||
pub rows: Vec<Vec<Expr>>,
|
||||
}
|
||||
|
||||
impl fmt::Display for Values {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.write_str("VALUES")?;
|
||||
match self.value_keyword {
|
||||
true => f.write_str("VALUE")?,
|
||||
false => f.write_str("VALUES")?,
|
||||
};
|
||||
let prefix = if self.explicit_row { "ROW" } else { "" };
|
||||
let mut delim = "";
|
||||
for row in &self.rows {
|
||||
|
|
|
|||
|
|
@ -223,6 +223,7 @@ impl Spanned for Values {
|
|||
fn span(&self) -> Span {
|
||||
let Values {
|
||||
explicit_row: _, // bool,
|
||||
value_keyword: _,
|
||||
rows,
|
||||
} = self;
|
||||
|
||||
|
|
|
|||
|
|
@ -12533,7 +12533,10 @@ impl<'a> Parser<'a> {
|
|||
SetExpr::Query(subquery)
|
||||
} else if self.parse_keyword(Keyword::VALUES) {
|
||||
let is_mysql = dialect_of!(self is MySqlDialect);
|
||||
SetExpr::Values(self.parse_values(is_mysql)?)
|
||||
SetExpr::Values(self.parse_values(is_mysql, false)?)
|
||||
} else if self.parse_keyword(Keyword::VALUE) {
|
||||
let is_mysql = dialect_of!(self is MySqlDialect);
|
||||
SetExpr::Values(self.parse_values(is_mysql, true)?)
|
||||
} else if self.parse_keyword(Keyword::TABLE) {
|
||||
SetExpr::Table(Box::new(self.parse_as_table()?))
|
||||
} else {
|
||||
|
|
@ -13837,7 +13840,7 @@ impl<'a> Parser<'a> {
|
|||
// 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 values = SetExpr::Values(self.parse_values(false, false)?);
|
||||
let alias = self.maybe_parse_table_alias()?;
|
||||
Ok(TableFactor::Derived {
|
||||
lateral: false,
|
||||
|
|
@ -16504,7 +16507,11 @@ impl<'a> Parser<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn parse_values(&mut self, allow_empty: bool) -> Result<Values, ParserError> {
|
||||
pub fn parse_values(
|
||||
&mut self,
|
||||
allow_empty: bool,
|
||||
value_keyword: bool,
|
||||
) -> Result<Values, ParserError> {
|
||||
let mut explicit_row = false;
|
||||
|
||||
let rows = self.parse_comma_separated(|parser| {
|
||||
|
|
@ -16522,7 +16529,11 @@ impl<'a> Parser<'a> {
|
|||
Ok(exprs)
|
||||
}
|
||||
})?;
|
||||
Ok(Values { explicit_row, rows })
|
||||
Ok(Values {
|
||||
explicit_row,
|
||||
rows,
|
||||
value_keyword,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn parse_start_transaction(&mut self) -> Result<Statement, ParserError> {
|
||||
|
|
@ -16937,7 +16948,7 @@ impl<'a> Parser<'a> {
|
|||
MergeInsertKind::Row
|
||||
} else {
|
||||
self.expect_keyword_is(Keyword::VALUES)?;
|
||||
let values = self.parse_values(is_mysql)?;
|
||||
let values = self.parse_values(is_mysql, false)?;
|
||||
MergeInsertKind::Values(values)
|
||||
};
|
||||
MergeAction::Insert(MergeInsertExpr { columns, kind })
|
||||
|
|
|
|||
|
|
@ -1807,6 +1807,7 @@ fn parse_merge() {
|
|||
let insert_action = MergeAction::Insert(MergeInsertExpr {
|
||||
columns: vec![Ident::new("product"), Ident::new("quantity")],
|
||||
kind: MergeInsertKind::Values(Values {
|
||||
value_keyword: false,
|
||||
explicit_row: false,
|
||||
rows: vec![vec![Expr::value(number("1")), Expr::value(number("2"))]],
|
||||
}),
|
||||
|
|
@ -1951,6 +1952,7 @@ fn parse_merge() {
|
|||
action: MergeAction::Insert(MergeInsertExpr {
|
||||
columns: vec![Ident::new("a"), Ident::new("b"),],
|
||||
kind: MergeInsertKind::Values(Values {
|
||||
value_keyword: false,
|
||||
explicit_row: false,
|
||||
rows: vec![vec![
|
||||
Expr::value(number("1")),
|
||||
|
|
@ -1965,6 +1967,7 @@ fn parse_merge() {
|
|||
action: MergeAction::Insert(MergeInsertExpr {
|
||||
columns: vec![],
|
||||
kind: MergeInsertKind::Values(Values {
|
||||
value_keyword: false,
|
||||
explicit_row: false,
|
||||
rows: vec![vec![
|
||||
Expr::value(number("1")),
|
||||
|
|
|
|||
|
|
@ -106,19 +106,19 @@ fn parse_insert_values() {
|
|||
let rows2 = vec![row.clone(), row];
|
||||
|
||||
let sql = "INSERT customer VALUES (1, 2, 3)";
|
||||
check_one(sql, "customer", &[], &rows1);
|
||||
check_one(sql, "customer", &[], &rows1, false);
|
||||
|
||||
let sql = "INSERT INTO customer VALUES (1, 2, 3)";
|
||||
check_one(sql, "customer", &[], &rows1);
|
||||
check_one(sql, "customer", &[], &rows1, false);
|
||||
|
||||
let sql = "INSERT INTO customer VALUES (1, 2, 3), (1, 2, 3)";
|
||||
check_one(sql, "customer", &[], &rows2);
|
||||
check_one(sql, "customer", &[], &rows2, false);
|
||||
|
||||
let sql = "INSERT INTO public.customer VALUES (1, 2, 3)";
|
||||
check_one(sql, "public.customer", &[], &rows1);
|
||||
check_one(sql, "public.customer", &[], &rows1, false);
|
||||
|
||||
let sql = "INSERT INTO db.public.customer VALUES (1, 2, 3)";
|
||||
check_one(sql, "db.public.customer", &[], &rows1);
|
||||
check_one(sql, "db.public.customer", &[], &rows1, false);
|
||||
|
||||
let sql = "INSERT INTO public.customer (id, name, active) VALUES (1, 2, 3)";
|
||||
check_one(
|
||||
|
|
@ -126,6 +126,16 @@ fn parse_insert_values() {
|
|||
"public.customer",
|
||||
&["id".to_string(), "name".to_string(), "active".to_string()],
|
||||
&rows1,
|
||||
false,
|
||||
);
|
||||
|
||||
let sql = r"INSERT INTO t (id, name, active) VALUE (1, 2, 3)";
|
||||
check_one(
|
||||
sql,
|
||||
"t",
|
||||
&["id".to_string(), "name".to_string(), "active".to_string()],
|
||||
&rows1,
|
||||
true,
|
||||
);
|
||||
|
||||
fn check_one(
|
||||
|
|
@ -133,6 +143,7 @@ fn parse_insert_values() {
|
|||
expected_table_name: &str,
|
||||
expected_columns: &[String],
|
||||
expected_rows: &[Vec<Expr>],
|
||||
expected_value_keyword: bool,
|
||||
) {
|
||||
match verified_stmt(sql) {
|
||||
Statement::Insert(Insert {
|
||||
|
|
@ -147,8 +158,13 @@ fn parse_insert_values() {
|
|||
assert_eq!(column, &Ident::new(expected_columns[index].clone()));
|
||||
}
|
||||
match *source.body {
|
||||
SetExpr::Values(Values { rows, .. }) => {
|
||||
assert_eq!(rows.as_slice(), expected_rows)
|
||||
SetExpr::Values(Values {
|
||||
rows,
|
||||
value_keyword,
|
||||
..
|
||||
}) => {
|
||||
assert_eq!(rows.as_slice(), expected_rows);
|
||||
assert!(value_keyword == expected_value_keyword);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
|
@ -9908,6 +9924,7 @@ fn parse_merge() {
|
|||
action: MergeAction::Insert(MergeInsertExpr {
|
||||
columns: vec![Ident::new("A"), Ident::new("B"), Ident::new("C")],
|
||||
kind: MergeInsertKind::Values(Values {
|
||||
value_keyword: false,
|
||||
explicit_row: false,
|
||||
rows: vec![vec![
|
||||
Expr::CompoundIdentifier(vec![
|
||||
|
|
|
|||
|
|
@ -157,6 +157,7 @@ fn test_databricks_lambdas() {
|
|||
#[test]
|
||||
fn test_values_clause() {
|
||||
let values = Values {
|
||||
value_keyword: false,
|
||||
explicit_row: false,
|
||||
rows: vec![
|
||||
vec![
|
||||
|
|
|
|||
|
|
@ -1885,6 +1885,7 @@ fn parse_simple_insert() {
|
|||
Some(Box::new(Query {
|
||||
with: None,
|
||||
body: Box::new(SetExpr::Values(Values {
|
||||
value_keyword: false,
|
||||
explicit_row: false,
|
||||
rows: vec![
|
||||
vec![
|
||||
|
|
@ -1950,6 +1951,7 @@ fn parse_ignore_insert() {
|
|||
Some(Box::new(Query {
|
||||
with: None,
|
||||
body: Box::new(SetExpr::Values(Values {
|
||||
value_keyword: false,
|
||||
explicit_row: false,
|
||||
rows: vec![vec![
|
||||
Expr::Value(
|
||||
|
|
@ -1999,6 +2001,7 @@ fn parse_priority_insert() {
|
|||
Some(Box::new(Query {
|
||||
with: None,
|
||||
body: Box::new(SetExpr::Values(Values {
|
||||
value_keyword: false,
|
||||
explicit_row: false,
|
||||
rows: vec![vec![
|
||||
Expr::Value(
|
||||
|
|
@ -2045,6 +2048,7 @@ fn parse_priority_insert() {
|
|||
Some(Box::new(Query {
|
||||
with: None,
|
||||
body: Box::new(SetExpr::Values(Values {
|
||||
value_keyword: false,
|
||||
explicit_row: false,
|
||||
rows: vec![vec![
|
||||
Expr::Value(
|
||||
|
|
@ -2097,6 +2101,7 @@ fn parse_insert_as() {
|
|||
Some(Box::new(Query {
|
||||
with: None,
|
||||
body: Box::new(SetExpr::Values(Values {
|
||||
value_keyword: false,
|
||||
explicit_row: false,
|
||||
rows: vec![vec![Expr::Value(
|
||||
(Value::SingleQuotedString("2024-01-01".to_string())).with_empty_span()
|
||||
|
|
@ -2156,6 +2161,7 @@ fn parse_insert_as() {
|
|||
Some(Box::new(Query {
|
||||
with: None,
|
||||
body: Box::new(SetExpr::Values(Values {
|
||||
value_keyword: false,
|
||||
explicit_row: false,
|
||||
rows: vec![vec![
|
||||
Expr::value(number("1")),
|
||||
|
|
@ -2206,6 +2212,7 @@ fn parse_replace_insert() {
|
|||
Some(Box::new(Query {
|
||||
with: None,
|
||||
body: Box::new(SetExpr::Values(Values {
|
||||
value_keyword: false,
|
||||
explicit_row: false,
|
||||
rows: vec![vec![
|
||||
Expr::Value(
|
||||
|
|
@ -2253,6 +2260,7 @@ fn parse_empty_row_insert() {
|
|||
Some(Box::new(Query {
|
||||
with: None,
|
||||
body: Box::new(SetExpr::Values(Values {
|
||||
value_keyword: false,
|
||||
explicit_row: false,
|
||||
rows: vec![vec![], vec![]]
|
||||
})),
|
||||
|
|
@ -2303,6 +2311,7 @@ fn parse_insert_with_on_duplicate_update() {
|
|||
Some(Box::new(Query {
|
||||
with: None,
|
||||
body: Box::new(SetExpr::Values(Values {
|
||||
value_keyword: false,
|
||||
explicit_row: false,
|
||||
rows: vec![vec![
|
||||
Expr::Value(
|
||||
|
|
|
|||
|
|
@ -5169,6 +5169,7 @@ fn test_simple_postgres_insert_with_alias() {
|
|||
source: Some(Box::new(Query {
|
||||
with: None,
|
||||
body: Box::new(SetExpr::Values(Values {
|
||||
value_keyword: false,
|
||||
explicit_row: false,
|
||||
rows: vec![vec![
|
||||
Expr::Identifier(Ident::new("DEFAULT")),
|
||||
|
|
@ -5238,6 +5239,7 @@ fn test_simple_postgres_insert_with_alias() {
|
|||
source: Some(Box::new(Query {
|
||||
with: None,
|
||||
body: Box::new(SetExpr::Values(Values {
|
||||
value_keyword: false,
|
||||
explicit_row: false,
|
||||
rows: vec![vec![
|
||||
Expr::Identifier(Ident::new("DEFAULT")),
|
||||
|
|
@ -5309,6 +5311,7 @@ fn test_simple_insert_with_quoted_alias() {
|
|||
source: Some(Box::new(Query {
|
||||
with: None,
|
||||
body: Box::new(SetExpr::Values(Values {
|
||||
value_keyword: false,
|
||||
explicit_row: false,
|
||||
rows: vec![vec![
|
||||
Expr::Identifier(Ident::new("DEFAULT")),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue