mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-26 17:04:10 +00:00
parent
2308c1c6f7
commit
1cef68e510
3 changed files with 80 additions and 3 deletions
|
@ -471,6 +471,7 @@ impl ToString for SQLStatement {
|
||||||
} => {
|
} => {
|
||||||
let mut s = format!("UPDATE {}", table_name.to_string());
|
let mut s = format!("UPDATE {}", table_name.to_string());
|
||||||
if !assignments.is_empty() {
|
if !assignments.is_empty() {
|
||||||
|
s += " SET ";
|
||||||
s += &comma_separated_string(assignments);
|
s += &comma_separated_string(assignments);
|
||||||
}
|
}
|
||||||
if let Some(selection) = selection {
|
if let Some(selection) = selection {
|
||||||
|
@ -560,13 +561,13 @@ impl ToString for SQLObjectName {
|
||||||
/// SQL assignment `foo = expr` as used in SQLUpdate
|
/// SQL assignment `foo = expr` as used in SQLUpdate
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct SQLAssignment {
|
pub struct SQLAssignment {
|
||||||
id: SQLIdent,
|
pub id: SQLIdent,
|
||||||
value: ASTNode,
|
pub value: ASTNode,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToString for SQLAssignment {
|
impl ToString for SQLAssignment {
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
format!("SET {} = {}", self.id, self.value.to_string())
|
format!("{} = {}", self.id, self.value.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -117,6 +117,7 @@ impl Parser {
|
||||||
"DROP" => Ok(self.parse_drop()?),
|
"DROP" => Ok(self.parse_drop()?),
|
||||||
"DELETE" => Ok(self.parse_delete()?),
|
"DELETE" => Ok(self.parse_delete()?),
|
||||||
"INSERT" => Ok(self.parse_insert()?),
|
"INSERT" => Ok(self.parse_insert()?),
|
||||||
|
"UPDATE" => Ok(self.parse_update()?),
|
||||||
"ALTER" => Ok(self.parse_alter()?),
|
"ALTER" => Ok(self.parse_alter()?),
|
||||||
"COPY" => Ok(self.parse_copy()?),
|
"COPY" => Ok(self.parse_copy()?),
|
||||||
_ => parser_err!(format!(
|
_ => parser_err!(format!(
|
||||||
|
@ -1606,6 +1607,31 @@ impl Parser {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_update(&mut self) -> Result<SQLStatement, ParserError> {
|
||||||
|
let table_name = self.parse_object_name()?;
|
||||||
|
self.expect_keyword("SET")?;
|
||||||
|
let mut assignments = vec![];
|
||||||
|
loop {
|
||||||
|
let id = self.parse_identifier()?;
|
||||||
|
self.expect_token(&Token::Eq)?;
|
||||||
|
let value = self.parse_expr()?;
|
||||||
|
assignments.push(SQLAssignment { id, value });
|
||||||
|
if !self.consume_token(&Token::Comma) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let selection = if self.parse_keyword("WHERE") {
|
||||||
|
Some(self.parse_expr()?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
Ok(SQLStatement::SQLUpdate {
|
||||||
|
table_name,
|
||||||
|
assignments,
|
||||||
|
selection,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Parse a comma-delimited list of SQL expressions
|
/// Parse a comma-delimited list of SQL expressions
|
||||||
pub fn parse_expr_list(&mut self) -> Result<Vec<ASTNode>, ParserError> {
|
pub fn parse_expr_list(&mut self) -> Result<Vec<ASTNode>, ParserError> {
|
||||||
let mut expr_list: Vec<ASTNode> = vec![];
|
let mut expr_list: Vec<ASTNode> = vec![];
|
||||||
|
|
|
@ -64,6 +64,56 @@ fn parse_insert_invalid() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_update() {
|
||||||
|
let sql = "UPDATE t SET a = 1, b = 2, c = 3 WHERE d";
|
||||||
|
match verified_stmt(sql) {
|
||||||
|
SQLStatement::SQLUpdate {
|
||||||
|
table_name,
|
||||||
|
assignments,
|
||||||
|
selection,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
assert_eq!(table_name.to_string(), "t".to_string());
|
||||||
|
assert_eq!(
|
||||||
|
assignments,
|
||||||
|
vec![
|
||||||
|
SQLAssignment {
|
||||||
|
id: "a".into(),
|
||||||
|
value: ASTNode::SQLValue(Value::Long(1)),
|
||||||
|
},
|
||||||
|
SQLAssignment {
|
||||||
|
id: "b".into(),
|
||||||
|
value: ASTNode::SQLValue(Value::Long(2)),
|
||||||
|
},
|
||||||
|
SQLAssignment {
|
||||||
|
id: "c".into(),
|
||||||
|
value: ASTNode::SQLValue(Value::Long(3)),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
assert_eq!(selection.unwrap(), ASTNode::SQLIdentifier("d".into()));
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
verified_stmt("UPDATE t SET a = 1, a = 2, a = 3");
|
||||||
|
|
||||||
|
let sql = "UPDATE t WHERE 1";
|
||||||
|
let res = parse_sql_statements(sql);
|
||||||
|
assert_eq!(
|
||||||
|
ParserError::ParserError("Expected SET, found: WHERE".to_string()),
|
||||||
|
res.unwrap_err()
|
||||||
|
);
|
||||||
|
|
||||||
|
let sql = "UPDATE t SET a = 1 extrabadstuff";
|
||||||
|
let res = parse_sql_statements(sql);
|
||||||
|
assert_eq!(
|
||||||
|
ParserError::ParserError("Expected end of statement, found: extrabadstuff".to_string()),
|
||||||
|
res.unwrap_err()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_invalid_table_name() {
|
fn parse_invalid_table_name() {
|
||||||
let ast = all_dialects().run_parser_method("db.public..customer", Parser::parse_object_name);
|
let ast = all_dialects().run_parser_method("db.public..customer", Parser::parse_object_name);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue