Skip to content

Commit

Permalink
reusing display impls
Browse files Browse the repository at this point in the history
  • Loading branch information
seve-martinez committed Sep 22, 2024
1 parent 2bdbd17 commit add9bb9
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 234 deletions.
177 changes: 69 additions & 108 deletions src/ast/dml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,84 +489,75 @@ pub struct Insert {

impl Display for Insert {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// Start building the insert statement.
if self.replace_into {
write!(f, "REPLACE INTO ")?;
let table_name = if let Some(alias) = &self.table_alias {
format!("{0} AS {alias}", self.table_name)
} else {
if self.ignore {
write!(f, "INSERT IGNORE ")?;
} else if let Some(priority) = &self.priority {
write!(f, "INSERT {} ", priority)?;
} else {
write!(f, "INSERT ")?;
}
self.table_name.to_string()
};

if self.into {
write!(f, "INTO ")?;
}
if self.table {
write!(f, "TABLE ")?;
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 table name and alias
write!(f, "{}", self.table_name)?;
if let Some(alias) = &self.table_alias {
write!(f, " AS {}", alias)?;
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 { "" },
)?;
}

// Write columns if there are any
if !self.columns.is_empty() {
let cols = self
.columns
.iter()
.map(|col| col.to_string())
.collect::<Vec<_>>()
.join(", ");
write!(f, " ({})", cols)?;
}

// Write partitioned insert (Hive)
if let Some(partitions) = &self.partitioned {
let parts = partitions
.iter()
.map(|p| p.to_string())
.collect::<Vec<_>>()
.join(", ");
write!(f, " PARTITION ({})", parts)?;
}

// Write after columns (Hive)
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() {
let after_cols = self
.after_columns
.iter()
.map(|col| col.to_string())
.collect::<Vec<_>>()
.join(", ");
write!(f, " ({})", after_cols)?;
write!(f, "({}) ", display_comma_separated(&self.after_columns))?;
}

// Write the source query if it exists
if let Some(source) = &self.source {
write!(f, " {}", source)?;
write!(f, "{source}")?;
}

// Write ON conflict handling for Sqlite, MySQL, etc.
if let Some(on_conflict) = &self.on {
write!(f, " {}", on_conflict)?;
if self.source.is_none() && self.columns.is_empty() {
write!(f, "DEFAULT VALUES")?;
}

// Write RETURNING clause if present
if let Some(returning) = &self.returning {
let returns = returning
.iter()
.map(|r| r.to_string())
.collect::<Vec<_>>()
.join(", ");
write!(f, " RETURNING {}", returns)?;
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(())
}
}
Expand Down Expand Up @@ -595,62 +586,32 @@ pub struct Delete {
impl Display for Delete {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "DELETE ")?;

// Handle multi-table DELETE if present
if !self.tables.is_empty() {
let tables = self
.tables
.iter()
.map(|t| t.to_string())
.collect::<Vec<_>>()
.join(", ");
write!(f, "{} ", tables)?;
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))?;
}
}

// The FromTable includes the `FROM` keyword.
write!(f, "{} ", self.from)?;

// USING clause (if present)
if let Some(using) = &self.using {
let uses = using
.iter()
.map(|tab| tab.to_string())
.collect::<Vec<_>>()
.join(", ");
write!(f, "USING {} ", uses)?;
write!(f, " USING {}", display_comma_separated(using))?;
}

// WHERE clause (if present)
if let Some(sel) = &self.selection {
write!(f, "WHERE {} ", sel)?;
if let Some(selection) = &self.selection {
write!(f, " WHERE {selection}")?;
}

// RETURNING clause (if present)
if let Some(ret) = &self.returning {
let rets = ret
.iter()
.map(|col| col.to_string())
.collect::<Vec<_>>()
.join(", ");
write!(f, "RETURNING {} ", rets)?;
if let Some(returning) = &self.returning {
write!(f, " RETURNING {}", display_comma_separated(returning))?;
}

// ORDER BY clause (if present)
if !self.order_by.is_empty() {
let order_by = self
.order_by
.iter()
.map(|ob| ob.to_string())
.collect::<Vec<_>>()
.join(", ");
write!(f, "ORDER BY {} ", order_by)?;
write!(f, " ORDER BY {}", display_comma_separated(&self.order_by))?;
}

// LIMIT clause (if present)
if let Some(limit) = &self.limit {
write!(f, "LIMIT {}", limit)?;
write!(f, " LIMIT {limit}")?;
}

Ok(())
}
}
128 changes: 2 additions & 126 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3418,93 +3418,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 @@ -3581,45 +3495,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

0 comments on commit add9bb9

Please sign in to comment.