mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-31 23:14:21 +01:00
when no context is needed use Display Impl
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
use crate::ast::{self, Expr};
|
||||
use std::fmt::Display;
|
||||
|
||||
use crate::ast::{self, fmt::ToTokens, Expr};
|
||||
|
||||
use super::ToSqlString;
|
||||
|
||||
@@ -30,7 +32,7 @@ impl ToSqlString for Expr {
|
||||
Expr::Binary(lhs, op, rhs) => {
|
||||
ret.push_str(&lhs.to_sql_string(context));
|
||||
ret.push(' ');
|
||||
ret.push_str(&op.to_sql_string(context));
|
||||
ret.push_str(&op.to_string());
|
||||
ret.push(' ');
|
||||
ret.push_str(&rhs.to_sql_string(context));
|
||||
}
|
||||
@@ -212,7 +214,7 @@ impl ToSqlString for Expr {
|
||||
if *not {
|
||||
ret.push_str("NOT ");
|
||||
}
|
||||
ret.push_str(&op.to_sql_string(context));
|
||||
ret.push_str(&op.to_string());
|
||||
ret.push(' ');
|
||||
ret.push_str(&rhs.to_sql_string(context));
|
||||
if let Some(escape) = escape {
|
||||
@@ -221,7 +223,7 @@ impl ToSqlString for Expr {
|
||||
}
|
||||
}
|
||||
Expr::Literal(literal) => {
|
||||
ret.push_str(&literal.to_sql_string(context));
|
||||
ret.push_str(&literal.to_string());
|
||||
}
|
||||
Expr::Name(name) => {
|
||||
ret.push_str(&name.0);
|
||||
@@ -247,7 +249,7 @@ impl ToSqlString for Expr {
|
||||
}
|
||||
Expr::Raise(resolve_type, expr) => {
|
||||
ret.push_str("RAISE(");
|
||||
ret.push_str(&resolve_type.to_sql_string(context));
|
||||
ret.push_str(&resolve_type.to_string());
|
||||
if let Some(expr) = expr {
|
||||
ret.push_str(", ");
|
||||
ret.push_str(&expr.to_sql_string(context));
|
||||
@@ -260,7 +262,7 @@ impl ToSqlString for Expr {
|
||||
ret.push(')');
|
||||
}
|
||||
Expr::Unary(unary_operator, expr) => {
|
||||
ret.push_str(&unary_operator.to_sql_string(context));
|
||||
ret.push_str(&unary_operator.to_string());
|
||||
ret.push(' ');
|
||||
ret.push_str(&expr.to_sql_string(context));
|
||||
}
|
||||
@@ -272,9 +274,9 @@ impl ToSqlString for Expr {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::Operator {
|
||||
fn to_sql_string<C: super::ToSqlContext>(&self, _context: &C) -> String {
|
||||
match self {
|
||||
impl Display for ast::Operator {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let value = match self {
|
||||
Self::Add => "+",
|
||||
Self::And => "AND",
|
||||
Self::ArrowRight => "->",
|
||||
@@ -298,8 +300,8 @@ impl ToSqlString for ast::Operator {
|
||||
Self::Or => "OR",
|
||||
Self::RightShift => ">>",
|
||||
Self::Subtract => "-",
|
||||
}
|
||||
.to_string()
|
||||
};
|
||||
write!(f, "{}", value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,16 +335,20 @@ impl ToSqlString for ast::TypeSize {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::Distinctness {
|
||||
fn to_sql_string<C: super::ToSqlContext>(&self, _context: &C) -> String {
|
||||
match self {
|
||||
Self::All => "ALL",
|
||||
Self::Distinct => "DISTINCT",
|
||||
}
|
||||
.to_string()
|
||||
impl Display for ast::Distinctness {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match self {
|
||||
Self::All => "ALL",
|
||||
Self::Distinct => "DISTINCT",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Can't impl Display here as it is already implemented for it
|
||||
impl ToSqlString for ast::QualifiedName {
|
||||
fn to_sql_string<C: super::ToSqlContext>(&self, _context: &C) -> String {
|
||||
let mut ret = String::new();
|
||||
@@ -359,55 +365,49 @@ impl ToSqlString for ast::QualifiedName {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::LikeOperator {
|
||||
fn to_sql_string<C: super::ToSqlContext>(&self, _context: &C) -> String {
|
||||
match self {
|
||||
Self::Glob => "GLOB",
|
||||
Self::Like => "LIKE",
|
||||
Self::Match => "MATCH",
|
||||
Self::Regexp => "REGEXP",
|
||||
}
|
||||
.to_string()
|
||||
impl Display for ast::LikeOperator {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.to_fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::Literal {
|
||||
fn to_sql_string<C: super::ToSqlContext>(&self, _context: &C) -> String {
|
||||
match self {
|
||||
Self::Blob(b) => format!("Ox{b}"),
|
||||
Self::CurrentDate => "CURRENT_DATE".to_string(),
|
||||
Self::CurrentTime => "CURRENT_TIME".to_string(),
|
||||
Self::CurrentTimestamp => "CURRENT_TIMESTAMP".to_string(),
|
||||
Self::Keyword(keyword) => keyword.clone(),
|
||||
Self::Null => "NULL".to_string(),
|
||||
Self::Numeric(num) => num.clone(),
|
||||
Self::String(s) => s.clone(),
|
||||
}
|
||||
impl Display for ast::Literal {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match self {
|
||||
Self::Blob(b) => format!("Ox{b}"),
|
||||
Self::CurrentDate => "CURRENT_DATE".to_string(),
|
||||
Self::CurrentTime => "CURRENT_TIME".to_string(),
|
||||
Self::CurrentTimestamp => "CURRENT_TIMESTAMP".to_string(),
|
||||
Self::Keyword(keyword) => keyword.clone(),
|
||||
Self::Null => "NULL".to_string(),
|
||||
Self::Numeric(num) => num.clone(),
|
||||
Self::String(s) => s.clone(),
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::ResolveType {
|
||||
fn to_sql_string<C: super::ToSqlContext>(&self, _context: &C) -> String {
|
||||
match self {
|
||||
Self::Abort => "ABORT",
|
||||
Self::Fail => "FAIL",
|
||||
Self::Ignore => "IGNORE",
|
||||
Self::Replace => "REPLACE",
|
||||
Self::Rollback => "ROLLBACK",
|
||||
}
|
||||
.to_string()
|
||||
impl Display for ast::ResolveType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.to_fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::UnaryOperator {
|
||||
fn to_sql_string<C: super::ToSqlContext>(&self, _context: &C) -> String {
|
||||
match self {
|
||||
Self::BitwiseNot => "~",
|
||||
Self::Negative => "-",
|
||||
Self::Not => "NOT",
|
||||
Self::Positive => "+",
|
||||
}
|
||||
.to_string()
|
||||
impl Display for ast::UnaryOperator {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match self {
|
||||
Self::BitwiseNot => "~",
|
||||
Self::Negative => "-",
|
||||
Self::Not => "NOT",
|
||||
Self::Positive => "+",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use crate::{ast, to_sql_string::ToSqlString};
|
||||
|
||||
impl ToSqlString for ast::AlterTableBody {
|
||||
@@ -60,15 +62,15 @@ impl ToSqlString for ast::ColumnConstraint {
|
||||
format!("DEFAULT ({})", expr.to_sql_string(context))
|
||||
}
|
||||
}
|
||||
Self::Defer(expr) => expr.to_sql_string(context),
|
||||
Self::Defer(expr) => expr.to_string(),
|
||||
Self::ForeignKey {
|
||||
clause,
|
||||
deref_clause,
|
||||
} => format!(
|
||||
"{}{}",
|
||||
clause.to_sql_string(context),
|
||||
clause.to_string(),
|
||||
if let Some(deref) = deref_clause {
|
||||
deref.to_sql_string(context)
|
||||
deref.to_string()
|
||||
} else {
|
||||
"".to_string()
|
||||
}
|
||||
@@ -94,7 +96,7 @@ impl ToSqlString for ast::ColumnConstraint {
|
||||
"NOT NULL{}",
|
||||
conflict_clause.map_or("".to_string(), |conflict| format!(
|
||||
" {}",
|
||||
conflict.to_sql_string(context)
|
||||
conflict.to_string()
|
||||
))
|
||||
)
|
||||
}
|
||||
@@ -105,13 +107,10 @@ impl ToSqlString for ast::ColumnConstraint {
|
||||
} => {
|
||||
format!(
|
||||
"PRIMARY KEY{}{}{}",
|
||||
order.map_or("".to_string(), |order| format!(
|
||||
" {}",
|
||||
order.to_sql_string(context)
|
||||
)),
|
||||
order.map_or("".to_string(), |order| format!(" {}", order.to_string())),
|
||||
conflict_clause.map_or("".to_string(), |conflict| format!(
|
||||
" {}",
|
||||
conflict.to_sql_string(context)
|
||||
conflict.to_string()
|
||||
)),
|
||||
auto_increment.then_some(" AUTOINCREMENT").unwrap_or("")
|
||||
)
|
||||
@@ -121,7 +120,7 @@ impl ToSqlString for ast::ColumnConstraint {
|
||||
"UNIQUE{}",
|
||||
conflict_clause.map_or("".to_string(), |conflict| format!(
|
||||
" {}",
|
||||
conflict.to_sql_string(context)
|
||||
conflict.to_string()
|
||||
))
|
||||
)
|
||||
}
|
||||
@@ -129,9 +128,9 @@ impl ToSqlString for ast::ColumnConstraint {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::ForeignKeyClause {
|
||||
fn to_sql_string<C: crate::to_sql_string::ToSqlContext>(&self, context: &C) -> String {
|
||||
format!(
|
||||
impl Display for ast::ForeignKeyClause {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let value = format!(
|
||||
"REFERENCES {}{}{}",
|
||||
self.tbl_name.0,
|
||||
if let Some(columns) = &self.columns {
|
||||
@@ -139,7 +138,7 @@ impl ToSqlString for ast::ForeignKeyClause {
|
||||
"({})",
|
||||
columns
|
||||
.iter()
|
||||
.map(|cols| cols.to_sql_string(context))
|
||||
.map(|cols| cols.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)
|
||||
@@ -151,46 +150,48 @@ impl ToSqlString for ast::ForeignKeyClause {
|
||||
" {}",
|
||||
self.args
|
||||
.iter()
|
||||
.map(|arg| arg.to_sql_string(context))
|
||||
.map(|arg| arg.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ")
|
||||
)
|
||||
} else {
|
||||
"".to_string()
|
||||
}
|
||||
)
|
||||
);
|
||||
write!(f, "{}", value)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::RefArg {
|
||||
fn to_sql_string<C: crate::to_sql_string::ToSqlContext>(&self, context: &C) -> String {
|
||||
match self {
|
||||
impl Display for ast::RefArg {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let value = match self {
|
||||
Self::Match(name) => format!("MATCH {}", name.0),
|
||||
Self::OnDelete(act) => format!("ON DELETE {}", act.to_sql_string(context)),
|
||||
Self::OnUpdate(act) => format!("ON UPDATE {}", act.to_sql_string(context)),
|
||||
Self::OnDelete(act) => format!("ON DELETE {}", act.to_string()),
|
||||
Self::OnUpdate(act) => format!("ON UPDATE {}", act.to_string()),
|
||||
Self::OnInsert(..) => unimplemented!(
|
||||
"On Insert does not exist in SQLite: https://www.sqlite.org/lang_altertable.html"
|
||||
),
|
||||
}
|
||||
};
|
||||
write!(f, "{}", value)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::RefAct {
|
||||
fn to_sql_string<C: crate::to_sql_string::ToSqlContext>(&self, _context: &C) -> String {
|
||||
match self {
|
||||
impl Display for ast::RefAct {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let value = match self {
|
||||
Self::Cascade => "CASCADE",
|
||||
Self::NoAction => "NO ACTION",
|
||||
Self::Restrict => "RESTRICT",
|
||||
Self::SetDefault => "SET DEFAULT",
|
||||
Self::SetNull => "SET NULL",
|
||||
}
|
||||
.to_string()
|
||||
};
|
||||
write!(f, "{}", value)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::DeferSubclause {
|
||||
fn to_sql_string<C: crate::to_sql_string::ToSqlContext>(&self, _context: &C) -> String {
|
||||
format!(
|
||||
impl Display for ast::DeferSubclause {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let value = format!(
|
||||
"{}{}",
|
||||
if self.deferrable {
|
||||
"NOT DEFERRABLE"
|
||||
@@ -205,7 +206,8 @@ impl ToSqlString for ast::DeferSubclause {
|
||||
} else {
|
||||
""
|
||||
}
|
||||
)
|
||||
);
|
||||
write!(f, "{}", value)
|
||||
}
|
||||
}
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use crate::{ast, to_sql_string::ToSqlString};
|
||||
|
||||
impl ToSqlString for ast::CreateTableBody {
|
||||
@@ -26,7 +28,7 @@ impl ToSqlString for ast::CreateTableBody {
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)),
|
||||
options.to_sql_string(context)
|
||||
options.to_string()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -59,12 +61,12 @@ impl ToSqlString for ast::TableConstraint {
|
||||
"FOREIGN KEY ({}) {}{}",
|
||||
columns
|
||||
.iter()
|
||||
.map(|col| col.to_sql_string(context))
|
||||
.map(|col| col.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
clause.to_sql_string(context),
|
||||
clause.to_string(),
|
||||
if let Some(deref) = deref_clause {
|
||||
deref.to_sql_string(context)
|
||||
deref.to_string()
|
||||
} else {
|
||||
"".to_string()
|
||||
}
|
||||
@@ -82,7 +84,7 @@ impl ToSqlString for ast::TableConstraint {
|
||||
.join(", "),
|
||||
conflict_clause.map_or("".to_string(), |conflict| format!(
|
||||
" {}",
|
||||
conflict.to_sql_string(context)
|
||||
conflict.to_string()
|
||||
)),
|
||||
auto_increment.then_some(" AUTOINCREMENT").unwrap_or("")
|
||||
),
|
||||
@@ -98,23 +100,26 @@ impl ToSqlString for ast::TableConstraint {
|
||||
.join(", "),
|
||||
conflict_clause.map_or("".to_string(), |conflict| format!(
|
||||
" {}",
|
||||
conflict.to_sql_string(context)
|
||||
conflict.to_string()
|
||||
))
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::TableOptions {
|
||||
fn to_sql_string<C: crate::to_sql_string::ToSqlContext>(&self, _context: &C) -> String {
|
||||
if *self == Self::NONE {
|
||||
""
|
||||
} else if *self == Self::STRICT {
|
||||
" STRICT"
|
||||
} else {
|
||||
" WITHOUT ROWID"
|
||||
}
|
||||
.to_string()
|
||||
impl Display for ast::TableOptions {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
if *self == Self::NONE {
|
||||
""
|
||||
} else if *self == Self::STRICT {
|
||||
" STRICT"
|
||||
} else {
|
||||
" WITHOUT ROWID"
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
use crate::{ast, to_sql_string::ToSqlString};
|
||||
use std::fmt::Display;
|
||||
|
||||
use crate::{
|
||||
ast::{self, fmt::ToTokens},
|
||||
to_sql_string::ToSqlString,
|
||||
};
|
||||
|
||||
impl ToSqlString for ast::CreateTrigger {
|
||||
fn to_sql_string<C: crate::to_sql_string::ToSqlContext>(&self, context: &C) -> String {
|
||||
@@ -7,11 +12,9 @@ impl ToSqlString for ast::CreateTrigger {
|
||||
self.temporary.then_some(" TEMP").unwrap_or(""),
|
||||
self.if_not_exists.then_some("IF NOT EXISTS ").unwrap_or(""),
|
||||
self.trigger_name.to_sql_string(context),
|
||||
self.time.map_or("".to_string(), |time| format!(
|
||||
" {}",
|
||||
time.to_sql_string(context)
|
||||
)),
|
||||
self.event.to_sql_string(context),
|
||||
self.time
|
||||
.map_or("".to_string(), |time| format!(" {}", time.to_string())),
|
||||
self.event.to_string(),
|
||||
self.tbl_name.to_sql_string(context),
|
||||
self.for_each_row.then_some(" FOR EACH ROW").unwrap_or(""),
|
||||
self.when_clause
|
||||
@@ -29,32 +32,31 @@ impl ToSqlString for ast::CreateTrigger {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::TriggerTime {
|
||||
fn to_sql_string<C: crate::to_sql_string::ToSqlContext>(&self, _context: &C) -> String {
|
||||
match self {
|
||||
Self::After => "AFTER",
|
||||
Self::Before => "BEFORE",
|
||||
Self::InsteadOf => "INSTEAD OF",
|
||||
}
|
||||
.to_string()
|
||||
impl Display for ast::TriggerTime {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.to_fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::TriggerEvent {
|
||||
fn to_sql_string<C: crate::to_sql_string::ToSqlContext>(&self, _context: &C) -> String {
|
||||
match self {
|
||||
Self::Delete => "DELETE".to_string(),
|
||||
Self::Insert => "INSERT".to_string(),
|
||||
Self::Update => "UPDATE".to_string(),
|
||||
Self::UpdateOf(col_names) => format!(
|
||||
"UPDATE OF {}",
|
||||
col_names
|
||||
.iter()
|
||||
.map(|name| name.0.clone())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
}
|
||||
impl Display for ast::TriggerEvent {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match self {
|
||||
Self::Delete => "DELETE".to_string(),
|
||||
Self::Insert => "INSERT".to_string(),
|
||||
Self::Update => "UPDATE".to_string(),
|
||||
Self::UpdateOf(col_names) => format!(
|
||||
"UPDATE OF {}",
|
||||
col_names
|
||||
.iter()
|
||||
.map(|name| name.0.clone())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +99,7 @@ impl ToSqlString for ast::TriggerCmdInsert {
|
||||
"INSERT {}INTO {} {}{}{}{}",
|
||||
self.or_conflict.map_or("".to_string(), |conflict| format!(
|
||||
"OR {} ",
|
||||
conflict.to_sql_string(context)
|
||||
conflict.to_string()
|
||||
)),
|
||||
self.tbl_name.0,
|
||||
self.col_names
|
||||
@@ -216,7 +218,7 @@ impl ToSqlString for ast::TriggerCmdUpdate {
|
||||
"UPDATE {}{} SET {}{}{}",
|
||||
self.or_conflict.map_or("".to_string(), |conflict| format!(
|
||||
"OR {}",
|
||||
conflict.to_sql_string(context)
|
||||
conflict.to_string()
|
||||
)),
|
||||
self.tbl_name.0, // TODO: should be a qualified table name,
|
||||
self.sets
|
||||
|
||||
@@ -13,7 +13,7 @@ impl ToSqlString for ast::Delete {
|
||||
.as_ref()
|
||||
.map_or("".to_string(), |indexed| format!(
|
||||
" {}",
|
||||
indexed.to_sql_string(context)
|
||||
indexed.to_string()
|
||||
)),
|
||||
self.where_clause
|
||||
.as_ref()
|
||||
|
||||
@@ -10,7 +10,7 @@ impl ToSqlString for ast::Insert {
|
||||
)),
|
||||
self.or_conflict.map_or("".to_string(), |conflict| format!(
|
||||
"OR {} ",
|
||||
conflict.to_sql_string(context)
|
||||
conflict.to_string()
|
||||
)),
|
||||
self.tbl_name.to_sql_string(context),
|
||||
self.columns
|
||||
|
||||
@@ -108,7 +108,7 @@ impl ToSqlString for ast::Stmt {
|
||||
" ({})",
|
||||
columns
|
||||
.iter()
|
||||
.map(|col| col.to_sql_string(context))
|
||||
.map(|col| col.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)),
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use crate::{
|
||||
ast::{self},
|
||||
ast::{self, fmt::ToTokens},
|
||||
to_sql_string::{ToSqlContext, ToSqlString},
|
||||
};
|
||||
|
||||
@@ -37,7 +39,7 @@ impl ToSqlString for ast::SelectBody {
|
||||
let compound_selects = compounds
|
||||
.iter()
|
||||
.map(|compound_select| {
|
||||
let mut curr = compound_select.operator.to_sql_string(context);
|
||||
let mut curr = compound_select.operator.to_string();
|
||||
curr.push(' ');
|
||||
curr.push_str(&compound_select.select.to_sql_string(context));
|
||||
curr
|
||||
@@ -78,7 +80,7 @@ impl ToSqlString for ast::SelectInner {
|
||||
let mut ret = Vec::with_capacity(2 + self.columns.len());
|
||||
ret.push("SELECT".to_string());
|
||||
if let Some(distinct) = self.distinctness {
|
||||
ret.push(distinct.to_sql_string(context));
|
||||
ret.push(distinct.to_string());
|
||||
}
|
||||
let joined_cols = self
|
||||
.columns
|
||||
@@ -124,7 +126,7 @@ impl ToSqlString for ast::FromClause {
|
||||
let joined_joins = joins
|
||||
.iter()
|
||||
.map(|join| {
|
||||
let mut curr = join.operator.to_sql_string(context);
|
||||
let mut curr = join.operator.to_string();
|
||||
curr.push(' ');
|
||||
curr.push_str(&join.table.to_sql_string(context));
|
||||
if let Some(join_constraint) = &join.constraint {
|
||||
@@ -149,11 +151,11 @@ impl ToSqlString for ast::SelectTable {
|
||||
ret.push_str(&name.to_sql_string(context));
|
||||
if let Some(alias) = alias {
|
||||
ret.push(' ');
|
||||
ret.push_str(&alias.to_sql_string(context));
|
||||
ret.push_str(&alias.to_string());
|
||||
}
|
||||
if let Some(indexed) = indexed {
|
||||
ret.push(' ');
|
||||
ret.push_str(&indexed.to_sql_string(context));
|
||||
ret.push_str(&indexed.to_string());
|
||||
}
|
||||
}
|
||||
Self::TableCall(table_func, args, alias) => {
|
||||
@@ -169,7 +171,7 @@ impl ToSqlString for ast::SelectTable {
|
||||
}
|
||||
if let Some(alias) = alias {
|
||||
ret.push(' ');
|
||||
ret.push_str(&alias.to_sql_string(context));
|
||||
ret.push_str(&alias.to_string());
|
||||
}
|
||||
}
|
||||
Self::Select(select, alias) => {
|
||||
@@ -178,7 +180,7 @@ impl ToSqlString for ast::SelectTable {
|
||||
ret.push(')');
|
||||
if let Some(alias) = alias {
|
||||
ret.push(' ');
|
||||
ret.push_str(&alias.to_sql_string(context));
|
||||
ret.push_str(&alias.to_string());
|
||||
}
|
||||
}
|
||||
Self::Sub(from_clause, alias) => {
|
||||
@@ -187,7 +189,7 @@ impl ToSqlString for ast::SelectTable {
|
||||
ret.push(')');
|
||||
if let Some(alias) = alias {
|
||||
ret.push(' ');
|
||||
ret.push_str(&alias.to_sql_string(context));
|
||||
ret.push_str(&alias.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -232,7 +234,7 @@ impl ToSqlString for ast::CommonTableExpr {
|
||||
if let Some(cols) = &self.columns {
|
||||
let joined_cols = cols
|
||||
.iter()
|
||||
.map(|col| col.to_sql_string(context))
|
||||
.map(|col| col.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
|
||||
@@ -241,7 +243,7 @@ impl ToSqlString for ast::CommonTableExpr {
|
||||
ret.push(format!(
|
||||
"AS {}({})",
|
||||
{
|
||||
let mut materialized = self.materialized.to_sql_string(context);
|
||||
let mut materialized = self.materialized.to_string();
|
||||
if !materialized.is_empty() {
|
||||
materialized.push(' ');
|
||||
}
|
||||
@@ -253,9 +255,9 @@ impl ToSqlString for ast::CommonTableExpr {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::IndexedColumn {
|
||||
fn to_sql_string<C: ToSqlContext>(&self, _context: &C) -> String {
|
||||
self.col_name.0.to_string()
|
||||
impl Display for ast::IndexedColumn {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.col_name.0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,56 +266,36 @@ impl ToSqlString for ast::SortedColumn {
|
||||
let mut curr = self.expr.to_sql_string(context);
|
||||
if let Some(sort_order) = self.order {
|
||||
curr.push(' ');
|
||||
curr.push_str(&sort_order.to_sql_string(context));
|
||||
curr.push_str(&sort_order.to_string());
|
||||
}
|
||||
if let Some(nulls_order) = self.nulls {
|
||||
curr.push(' ');
|
||||
curr.push_str(&nulls_order.to_sql_string(context));
|
||||
curr.push_str(&nulls_order.to_string());
|
||||
}
|
||||
curr
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::SortOrder {
|
||||
fn to_sql_string<C: ToSqlContext>(&self, _context: &C) -> String {
|
||||
match self {
|
||||
Self::Asc => "ASC",
|
||||
Self::Desc => "DESC",
|
||||
}
|
||||
.to_string()
|
||||
impl Display for ast::SortOrder {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.to_fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::NullsOrder {
|
||||
fn to_sql_string<C: ToSqlContext>(&self, _context: &C) -> String {
|
||||
match self {
|
||||
Self::First => "NULLS FIRST",
|
||||
Self::Last => "NULLS LAST",
|
||||
}
|
||||
.to_string()
|
||||
impl Display for ast::NullsOrder {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.to_fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::Materialized {
|
||||
fn to_sql_string<C: ToSqlContext>(&self, _context: &C) -> String {
|
||||
match self {
|
||||
impl Display for ast::Materialized {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let value = match self {
|
||||
Self::Any => "",
|
||||
Self::No => "NOT MATERIALIZED",
|
||||
Self::Yes => "MATERIALIZED",
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::CompoundOperator {
|
||||
fn to_sql_string<C: ToSqlContext>(&self, _context: &C) -> String {
|
||||
match self {
|
||||
Self::Except => "EXCEPT",
|
||||
Self::Intersect => "INTERSECT",
|
||||
Self::Union => "UNION",
|
||||
Self::UnionAll => "UNION ALL",
|
||||
}
|
||||
.to_string()
|
||||
};
|
||||
write!(f, "{}", value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,7 +307,7 @@ impl ToSqlString for ast::ResultColumn {
|
||||
ret.push_str(&expr.to_sql_string(context));
|
||||
if let Some(alias) = alias {
|
||||
ret.push(' ');
|
||||
ret.push_str(&alias.to_sql_string(context));
|
||||
ret.push_str(&alias.to_string());
|
||||
}
|
||||
}
|
||||
Self::Star => {
|
||||
@@ -339,70 +321,85 @@ impl ToSqlString for ast::ResultColumn {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::As {
|
||||
fn to_sql_string<C: ToSqlContext>(&self, _context: &C) -> String {
|
||||
match self {
|
||||
Self::As(alias) => {
|
||||
format!("AS {}", alias.0)
|
||||
impl Display for ast::As {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match self {
|
||||
Self::As(alias) => {
|
||||
format!("AS {}", alias.0)
|
||||
}
|
||||
Self::Elided(alias) => alias.0.clone(),
|
||||
}
|
||||
Self::Elided(alias) => alias.0.clone(),
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::Indexed {
|
||||
fn to_sql_string<C: ToSqlContext>(&self, _context: &C) -> String {
|
||||
match self {
|
||||
Self::NotIndexed => "NOT INDEXED".to_string(),
|
||||
Self::IndexedBy(name) => format!("INDEXED BY {}", name.0),
|
||||
}
|
||||
impl Display for ast::Indexed {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match self {
|
||||
Self::NotIndexed => "NOT INDEXED".to_string(),
|
||||
Self::IndexedBy(name) => format!("INDEXED BY {}", name.0),
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::JoinOperator {
|
||||
fn to_sql_string<C: ToSqlContext>(&self, context: &C) -> String {
|
||||
match self {
|
||||
Self::Comma => ",".to_string(),
|
||||
Self::TypedJoin(join) => {
|
||||
let join_keyword = "JOIN";
|
||||
if let Some(join) = join {
|
||||
format!("{} {}", join.to_sql_string(context), join_keyword)
|
||||
} else {
|
||||
join_keyword.to_string()
|
||||
impl Display for ast::JoinOperator {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match self {
|
||||
Self::Comma => ",".to_string(),
|
||||
Self::TypedJoin(join) => {
|
||||
let join_keyword = "JOIN";
|
||||
if let Some(join) = join {
|
||||
format!("{} {}", join.to_string(), join_keyword)
|
||||
} else {
|
||||
join_keyword.to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::JoinType {
|
||||
fn to_sql_string<C: ToSqlContext>(&self, _context: &C) -> String {
|
||||
let mut modifiers = Vec::new();
|
||||
if self.contains(Self::NATURAL) {
|
||||
modifiers.push("NATURAL");
|
||||
}
|
||||
if self.contains(Self::LEFT) || self.contains(Self::RIGHT) {
|
||||
// TODO: I think the parser incorrectly asigns outer to every LEFT and RIGHT query
|
||||
if self.contains(Self::LEFT | Self::RIGHT) {
|
||||
modifiers.push("FULL");
|
||||
} else if self.contains(Self::LEFT) {
|
||||
modifiers.push("LEFT");
|
||||
} else if self.contains(Self::RIGHT) {
|
||||
modifiers.push("RIGHT");
|
||||
impl Display for ast::JoinType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let value = {
|
||||
let mut modifiers = Vec::new();
|
||||
if self.contains(Self::NATURAL) {
|
||||
modifiers.push("NATURAL");
|
||||
}
|
||||
if self.contains(Self::LEFT) || self.contains(Self::RIGHT) {
|
||||
// TODO: I think the parser incorrectly asigns outer to every LEFT and RIGHT query
|
||||
if self.contains(Self::LEFT | Self::RIGHT) {
|
||||
modifiers.push("FULL");
|
||||
} else if self.contains(Self::LEFT) {
|
||||
modifiers.push("LEFT");
|
||||
} else if self.contains(Self::RIGHT) {
|
||||
modifiers.push("RIGHT");
|
||||
}
|
||||
// FIXME: ignore outer joins as I think they are parsed incorrectly in the bitflags
|
||||
// if self.contains(Self::OUTER) {
|
||||
// modifiers.push("OUTER");
|
||||
// }
|
||||
}
|
||||
// FIXME: ignore outer joins as I think they are parsed incorrectly in the bitflags
|
||||
// if self.contains(Self::OUTER) {
|
||||
// modifiers.push("OUTER");
|
||||
// }
|
||||
}
|
||||
|
||||
if self.contains(Self::INNER) {
|
||||
modifiers.push("INNER");
|
||||
}
|
||||
if self.contains(Self::CROSS) {
|
||||
modifiers.push("CROSS");
|
||||
}
|
||||
modifiers.join(" ")
|
||||
if self.contains(Self::INNER) {
|
||||
modifiers.push("INNER");
|
||||
}
|
||||
if self.contains(Self::CROSS) {
|
||||
modifiers.push("CROSS");
|
||||
}
|
||||
modifiers.join(" ")
|
||||
};
|
||||
write!(f, "{}", value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -479,7 +476,7 @@ impl ToSqlString for ast::Window {
|
||||
impl ToSqlString for ast::FrameClause {
|
||||
fn to_sql_string<C: ToSqlContext>(&self, context: &C) -> String {
|
||||
let mut ret = Vec::new();
|
||||
ret.push(self.mode.to_sql_string(context));
|
||||
ret.push(self.mode.to_string());
|
||||
let start_sql = self.start.to_sql_string(context);
|
||||
if let Some(end) = &self.end {
|
||||
ret.push(format!(
|
||||
@@ -491,21 +488,16 @@ impl ToSqlString for ast::FrameClause {
|
||||
ret.push(start_sql);
|
||||
}
|
||||
if let Some(exclude) = &self.exclude {
|
||||
ret.push(exclude.to_sql_string(context));
|
||||
ret.push(exclude.to_string());
|
||||
}
|
||||
|
||||
ret.join(" ")
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::FrameMode {
|
||||
fn to_sql_string<C: ToSqlContext>(&self, _context: &C) -> String {
|
||||
match self {
|
||||
Self::Groups => "GROUPS",
|
||||
Self::Range => "RANGE",
|
||||
Self::Rows => "ROWS",
|
||||
}
|
||||
.to_string()
|
||||
impl Display for ast::FrameMode {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.to_fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -521,15 +513,17 @@ impl ToSqlString for ast::FrameBound {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::FrameExclude {
|
||||
fn to_sql_string<C: ToSqlContext>(&self, _context: &C) -> String {
|
||||
let clause = match self {
|
||||
Self::CurrentRow => "CURRENT ROW",
|
||||
Self::Group => "GROUP",
|
||||
Self::NoOthers => "NO OTHERS",
|
||||
Self::Ties => "TIES",
|
||||
};
|
||||
format!("EXCLUDE {}", clause)
|
||||
impl Display for ast::FrameExclude {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", {
|
||||
let clause = match self {
|
||||
Self::CurrentRow => "CURRENT ROW",
|
||||
Self::Group => "GROUP",
|
||||
Self::NoOthers => "NO OTHERS",
|
||||
Self::Ties => "TIES",
|
||||
};
|
||||
format!("EXCLUDE {}", clause)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -658,4 +652,22 @@ mod tests {
|
||||
);
|
||||
|
||||
to_sql_string_test!(test_select_with_aggregate_window, "SELECT a, SUM(b) OVER (PARTITION BY c ORDER BY d ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS running_sum FROM t;");
|
||||
|
||||
to_sql_string_test!(
|
||||
test_select_with_exclude,
|
||||
"SELECT
|
||||
c.name,
|
||||
o.order_id,
|
||||
o.order_amount,
|
||||
SUM(o.order_amount) OVER (PARTITION BY c.id
|
||||
ORDER BY o.order_date
|
||||
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
|
||||
EXCLUDE CURRENT ROW) AS running_total_excluding_current
|
||||
FROM customers c
|
||||
JOIN orders o ON c.id = o.customer_id
|
||||
WHERE EXISTS (SELECT 1
|
||||
FROM orders o2
|
||||
WHERE o2.customer_id = c.id
|
||||
AND o2.order_amount > 1000);"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,14 +10,14 @@ impl ToSqlString for ast::Update {
|
||||
)),
|
||||
self.or_conflict.map_or("".to_string(), |conflict| format!(
|
||||
"OR {} ",
|
||||
conflict.to_sql_string(context)
|
||||
conflict.to_string()
|
||||
)),
|
||||
self.tbl_name.to_sql_string(context),
|
||||
self.indexed
|
||||
.as_ref()
|
||||
.map_or("".to_string(), |indexed| format!(
|
||||
" {}",
|
||||
indexed.to_sql_string(context)
|
||||
indexed.to_string()
|
||||
)),
|
||||
self.sets
|
||||
.iter()
|
||||
|
||||
Reference in New Issue
Block a user