Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
108 changes: 108 additions & 0 deletions src/ast/dml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,81 @@ pub struct Insert {
pub insert_alias: Option<InsertAliases>,
}

impl Display for Insert {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let table_name = if let Some(alias) = &self.table_alias {
format!("{0} AS {alias}", self.table_name)
} else {
self.table_name.to_string()
};

if let Some(action) = self.or {
write!(f, "INSERT OR {action} INTO {table_name} ")?;
} else {
write!(
f,
"{start}",
start = if self.replace_into {
"REPLACE"
} else {
"INSERT"
},
)?;
if let Some(priority) = self.priority {
write!(f, " {priority}",)?;
}

write!(
f,
"{ignore}{over}{int}{tbl} {table_name} ",
table_name = table_name,
ignore = if self.ignore { " IGNORE" } else { "" },
over = if self.overwrite { " OVERWRITE" } else { "" },
int = if self.into { " INTO" } else { "" },
tbl = if self.table { " TABLE" } else { "" },
)?;
}
if !self.columns.is_empty() {
write!(f, "({}) ", display_comma_separated(&self.columns))?;
}
if let Some(ref parts) = self.partitioned {
if !parts.is_empty() {
write!(f, "PARTITION ({}) ", display_comma_separated(parts))?;
}
}
if !self.after_columns.is_empty() {
write!(f, "({}) ", display_comma_separated(&self.after_columns))?;
}

if let Some(source) = &self.source {
write!(f, "{source}")?;
}

if self.source.is_none() && self.columns.is_empty() {
write!(f, "DEFAULT VALUES")?;
}

if let Some(insert_alias) = &self.insert_alias {
write!(f, " AS {0}", insert_alias.row_alias)?;

if let Some(col_aliases) = &insert_alias.col_aliases {
if !col_aliases.is_empty() {
write!(f, " ({})", display_comma_separated(col_aliases))?;
}
}
}

if let Some(on) = &self.on {
write!(f, "{on}")?;
}

if let Some(returning) = &self.returning {
write!(f, " RETURNING {}", display_comma_separated(returning))?;
}
Ok(())
}
}

/// DELETE statement.
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
Expand All @@ -512,3 +587,36 @@ pub struct Delete {
/// LIMIT (MySQL)
pub limit: Option<Expr>,
}

impl Display for Delete {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "DELETE ")?;
if !self.tables.is_empty() {
write!(f, "{} ", display_comma_separated(&self.tables))?;
}
match &self.from {
FromTable::WithFromKeyword(from) => {
write!(f, "FROM {}", display_comma_separated(from))?;
}
FromTable::WithoutKeyword(from) => {
write!(f, "{}", display_comma_separated(from))?;
}
}
if let Some(using) = &self.using {
write!(f, " USING {}", display_comma_separated(using))?;
}
if let Some(selection) = &self.selection {
write!(f, " WHERE {selection}")?;
}
if let Some(returning) = &self.returning {
write!(f, " RETURNING {}", display_comma_separated(returning))?;
}
if !self.order_by.is_empty() {
write!(f, " ORDER BY {}", display_comma_separated(&self.order_by))?;
}
if let Some(limit) = &self.limit {
write!(f, " LIMIT {limit}")?;
}
Ok(())
}
}
140 changes: 14 additions & 126 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2149,6 +2149,18 @@ pub enum FromTable {
/// <https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax#delete_statement>
WithoutKeyword(Vec<TableWithJoins>),
}
impl Display for FromTable {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
FromTable::WithFromKeyword(tables) => {
write!(f, "FROM {}", display_comma_separated(tables))
}
FromTable::WithoutKeyword(tables) => {
write!(f, "{}", display_comma_separated(tables))
}
}
}
}

/// Policy type for a `CREATE POLICY` statement.
/// ```sql
Expand Down Expand Up @@ -3497,93 +3509,7 @@ impl fmt::Display for Statement {
}
Ok(())
}
Statement::Insert(insert) => {
let Insert {
or,
ignore,
into,
table_name,
table_alias,
overwrite,
partitioned,
columns,
after_columns,
source,
table,
on,
returning,
replace_into,
priority,
insert_alias,
} = insert;
let table_name = if let Some(alias) = table_alias {
format!("{table_name} AS {alias}")
} else {
table_name.to_string()
};

if let Some(action) = or {
write!(f, "INSERT OR {action} INTO {table_name} ")?;
} else {
write!(
f,
"{start}",
start = if *replace_into { "REPLACE" } else { "INSERT" },
)?;
if let Some(priority) = priority {
write!(f, " {priority}",)?;
}

write!(
f,
"{ignore}{over}{int}{tbl} {table_name} ",
table_name = table_name,
ignore = if *ignore { " IGNORE" } else { "" },
over = if *overwrite { " OVERWRITE" } else { "" },
int = if *into { " INTO" } else { "" },
tbl = if *table { " TABLE" } else { "" },
)?;
}
if !columns.is_empty() {
write!(f, "({}) ", display_comma_separated(columns))?;
}
if let Some(ref parts) = partitioned {
if !parts.is_empty() {
write!(f, "PARTITION ({}) ", display_comma_separated(parts))?;
}
}
if !after_columns.is_empty() {
write!(f, "({}) ", display_comma_separated(after_columns))?;
}

if let Some(source) = source {
write!(f, "{source}")?;
}

if source.is_none() && columns.is_empty() {
write!(f, "DEFAULT VALUES")?;
}

if let Some(insert_alias) = insert_alias {
write!(f, " AS {0}", insert_alias.row_alias)?;

if let Some(col_aliases) = &insert_alias.col_aliases {
if !col_aliases.is_empty() {
write!(f, " ({})", display_comma_separated(col_aliases))?;
}
}
}

if let Some(on) = on {
write!(f, "{on}")?;
}

if let Some(returning) = returning {
write!(f, " RETURNING {}", display_comma_separated(returning))?;
}

Ok(())
}
Statement::Insert(insert) => write!(f, "{insert}"),
Statement::Install {
extension_name: name,
} => write!(f, "INSTALL {name}"),
Expand Down Expand Up @@ -3660,45 +3586,7 @@ impl fmt::Display for Statement {
}
Ok(())
}
Statement::Delete(delete) => {
let Delete {
tables,
from,
using,
selection,
returning,
order_by,
limit,
} = delete;
write!(f, "DELETE ")?;
if !tables.is_empty() {
write!(f, "{} ", display_comma_separated(tables))?;
}
match from {
FromTable::WithFromKeyword(from) => {
write!(f, "FROM {}", display_comma_separated(from))?;
}
FromTable::WithoutKeyword(from) => {
write!(f, "{}", display_comma_separated(from))?;
}
}
if let Some(using) = using {
write!(f, " USING {}", display_comma_separated(using))?;
}
if let Some(selection) = selection {
write!(f, " WHERE {selection}")?;
}
if let Some(returning) = returning {
write!(f, " RETURNING {}", display_comma_separated(returning))?;
}
if !order_by.is_empty() {
write!(f, " ORDER BY {}", display_comma_separated(order_by))?;
}
if let Some(limit) = limit {
write!(f, " LIMIT {limit}")?;
}
Ok(())
}
Statement::Delete(delete) => write!(f, "{delete}"),
Statement::Close { cursor } => {
write!(f, "CLOSE {cursor}")?;

Expand Down
Loading