Implement insert statements for subqueries (#4760)

This commit is contained in:
Mees Delzenne 2024-09-13 16:38:39 +02:00 committed by GitHub
parent 1a1278fc3a
commit 211a02d1ef
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 38 additions and 20 deletions

View file

@ -141,7 +141,7 @@ impl fmt::Display for InsertStatement {
if let Some(into) = &self.into {
write!(f, " INTO {}", into)?;
}
write!(f, "{}", self.data)?;
write!(f, " {}", self.data)?;
if let Some(ref v) = self.update {
write!(f, " {v}")?
}

View file

@ -79,6 +79,7 @@ impl Parser<'_> {
t!("RETURN")
| t!("SELECT")
| t!("CREATE")
| t!("INSERT")
| t!("UPSERT")
| t!("UPDATE")
| t!("DELETE")
@ -499,6 +500,11 @@ impl Parser<'_> {
let stmt = ctx.run(|ctx| self.parse_create_stmt(ctx)).await?;
Subquery::Create(stmt)
}
t!("INSERT") => {
self.pop_peek();
let stmt = ctx.run(|ctx| self.parse_insert_stmt(ctx)).await?;
Subquery::Insert(stmt)
}
t!("UPSERT") => {
self.pop_peek();
let stmt = ctx.run(|ctx| self.parse_upsert_stmt(ctx)).await?;
@ -608,6 +614,11 @@ impl Parser<'_> {
let stmt = ctx.run(|ctx| self.parse_create_stmt(ctx)).await?;
Subquery::Create(stmt)
}
t!("INSERT") => {
self.pop_peek();
let stmt = ctx.run(|ctx| self.parse_insert_stmt(ctx)).await?;
Subquery::Insert(stmt)
}
t!("UPSERT") => {
self.pop_peek();
let stmt = ctx.run(|ctx| self.parse_upsert_stmt(ctx)).await?;
@ -667,25 +678,6 @@ impl Parser<'_> {
Ok(res)
}
fn starts_disallowed_subquery_statement(kind: TokenKind) -> bool {
matches!(
kind,
t!("ANALYZE")
| t!("BEGIN")
| t!("BREAK")
| t!("CANCEL")
| t!("COMMIT")
| t!("CONTINUE")
| t!("FOR") | t!("INFO")
| t!("KILL") | t!("LIVE")
| t!("OPTION")
| t!("LET") | t!("SHOW")
| t!("SLEEP")
| t!("THROW")
| t!("USE")
)
}
/// Parses a strand with legacy rules, parsing to a record id, datetime or uuid if the string
/// matches.
pub(super) async fn reparse_legacy_strand(
@ -774,6 +766,13 @@ mod tests {
assert_eq!("(REMOVE EVENT foo_event ON foo)", format!("{}", out))
}
#[test]
fn subquery_insert_statment() {
let sql = "(INSERT INTO test [])";
let out = Value::parse(sql);
assert_eq!("(INSERT INTO test [])", format!("{}", out))
}
#[test]
fn mock_count() {
let sql = "|test:1000|";

View file

@ -115,4 +115,23 @@ impl Parser<'_> {
pub(super) fn kind_starts_expression(kind: TokenKind) -> bool {
matches!(kind, t!("..") | t!("<") | t!("->")) | Self::kind_starts_prime_value(kind)
}
pub(super) fn starts_disallowed_subquery_statement(kind: TokenKind) -> bool {
matches!(
kind,
t!("ANALYZE")
| t!("BEGIN")
| t!("BREAK")
| t!("CANCEL")
| t!("COMMIT")
| t!("CONTINUE")
| t!("FOR") | t!("INFO")
| t!("KILL") | t!("LIVE")
| t!("OPTION")
| t!("LET") | t!("SHOW")
| t!("SLEEP")
| t!("THROW")
| t!("USE")
)
}
}