diff --git a/core/incremental/view.rs b/core/incremental/view.rs index bcae0afae..e7ba76980 100644 --- a/core/incremental/view.rs +++ b/core/incremental/view.rs @@ -140,14 +140,7 @@ impl IncrementalView { Parser::new(sql.as_bytes()).next_cmd() { // Compare the SELECT statements as SQL strings - use turso_parser::ast::fmt::ToTokens; - - // Format both SELECT statements and compare - if let (Ok(current_sql), Ok(provided_sql)) = - (self.select_stmt.format(), select.format()) - { - return current_sql == provided_sql; - } + return self.select_stmt == select; } false } diff --git a/core/translate/alter.rs b/core/translate/alter.rs index 3c74ad242..6cf70fd14 100644 --- a/core/translate/alter.rs +++ b/core/translate/alter.rs @@ -1,8 +1,5 @@ use std::sync::Arc; -use turso_parser::{ - ast::{self, fmt::ToTokens as _}, - parser::Parser, -}; +use turso_parser::{ast, parser::Parser}; use crate::{ function::{AlterTableFunc, Func}, @@ -413,7 +410,7 @@ pub fn translate_alter_table( program.emit_string8_new_reg(from.to_string()); program.mark_last_insn_constant(); - program.emit_string8_new_reg(definition.format().unwrap()); + program.emit_string8_new_reg(definition.to_string()); program.mark_last_insn_constant(); let out = program.alloc_registers(sqlite_schema_column_len); diff --git a/core/translate/display.rs b/core/translate/display.rs index 631e5a295..f183bc3e8 100644 --- a/core/translate/display.rs +++ b/core/translate/display.rs @@ -3,7 +3,7 @@ use std::fmt::{Display, Formatter}; use turso_parser::{ ast::{ self, - fmt::{ToSqlContext, ToTokens, TokenStream}, + fmt::{BlankContext, ToSqlContext, ToTokens, TokenStream}, SortOrder, TableInternalId, }, token::TokenType, @@ -235,44 +235,40 @@ pub struct PlanContext<'a>(pub &'a [&'a TableReferences]); // Definitely not perfect yet impl ToSqlContext for PlanContext<'_> { - fn get_column_name(&self, table_id: TableInternalId, col_idx: usize) -> String { + fn get_column_name(&self, table_id: TableInternalId, col_idx: usize) -> Option> { let table = self .0 .iter() - .find_map(|table_ref| table_ref.find_table_by_internal_id(table_id)) - .unwrap(); + .find_map(|table_ref| table_ref.find_table_by_internal_id(table_id))?; let cols = table.columns(); - match cols.get(col_idx).unwrap().name.as_ref() { - None => format!("{col_idx}"), - Some(n) => n.to_string(), - } + cols.get(col_idx) + .map(|col| col.name.as_ref().map(|name| name.as_ref())) } - fn get_table_name(&self, id: TableInternalId) -> &str { + fn get_table_name(&self, id: TableInternalId) -> Option<&str> { let table_ref = self .0 .iter() - .find(|table_ref| table_ref.find_table_by_internal_id(id).is_some()) - .unwrap(); + .find(|table_ref| table_ref.find_table_by_internal_id(id).is_some())?; let joined_table = table_ref.find_joined_table_by_internal_id(id); let outer_query = table_ref.find_outer_query_ref_by_internal_id(id); match (joined_table, outer_query) { - (Some(table), None) => &table.identifier, - (None, Some(table)) => &table.identifier, + (Some(table), None) => Some(&table.identifier), + (None, Some(table)) => Some(&table.identifier), _ => unreachable!(), } } } impl ToTokens for Plan { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { match self { Self::Select(select) => { - select.to_tokens_with_context(s, &PlanContext(&[&select.table_references]))?; + select.to_tokens(s, &PlanContext(&[&select.table_references]))?; } Self::CompoundSelect { left, @@ -289,11 +285,11 @@ impl ToTokens for Plan { let context = &PlanContext(all_refs.as_slice()); for (plan, operator) in left { - plan.to_tokens_with_context(s, context)?; - operator.to_tokens_with_context(s, context)?; + plan.to_tokens(s, context)?; + operator.to_tokens(s, context)?; } - right_most.to_tokens_with_context(s, context)?; + right_most.to_tokens(s, context)?; if let Some(order_by) = order_by { s.append(TokenType::TK_ORDER, None)?; @@ -319,16 +315,22 @@ impl ToTokens for Plan { s.append(TokenType::TK_FLOAT, Some(&offset.to_string()))?; } } - Self::Delete(delete) => delete.to_tokens_with_context(s, context)?, - Self::Update(update) => update.to_tokens_with_context(s, context)?, + Self::Delete(delete) => delete.to_tokens(s, context)?, + Self::Update(update) => update.to_tokens(s, context)?, } Ok(()) } } +impl Display for JoinedTable { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + self.displayer(&BlankContext).fmt(f) + } +} + impl ToTokens for JoinedTable { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, _context: &C, @@ -345,7 +347,7 @@ impl ToTokens for JoinedTable { Table::FromClauseSubquery(from_clause_subquery) => { s.append(TokenType::TK_LP, None)?; // Could possibly merge the contexts together here - from_clause_subquery.plan.to_tokens_with_context( + from_clause_subquery.plan.to_tokens( s, &PlanContext(&[&from_clause_subquery.plan.table_references]), )?; @@ -362,7 +364,7 @@ impl ToTokens for JoinedTable { // TODO: currently cannot print the original CTE as it is optimized into a subquery impl ToTokens for SelectPlan { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -374,7 +376,7 @@ impl ToTokens for SelectPlan { .map(|values| values.iter().map(|v| Box::from(v.clone())).collect()) .collect(), ) - .to_tokens_with_context(s, context)?; + .to_tokens(s, context)?; } else { s.append(TokenType::TK_SELECT, None)?; if self.distinctness.is_distinct() { @@ -386,7 +388,7 @@ impl ToTokens for SelectPlan { s.append(TokenType::TK_COMMA, None)?; } - expr.to_tokens_with_context(s, context)?; + expr.to_tokens(s, context)?; if let Some(alias) = alias { s.append(TokenType::TK_AS, None)?; s.append(TokenType::TK_ID, Some(alias))?; @@ -403,7 +405,7 @@ impl ToTokens for SelectPlan { } let table_ref = self.joined_tables().get(order.original_idx).unwrap(); - table_ref.to_tokens_with_context(s, context)?; + table_ref.to_tokens(s, context)?; } if !self.where_clause.is_empty() { @@ -418,7 +420,7 @@ impl ToTokens for SelectPlan { if i != 0 { s.append(TokenType::TK_AND, None)?; } - expr.to_tokens_with_context(s, context)?; + expr.to_tokens(s, context)?; } } @@ -436,7 +438,7 @@ impl ToTokens for SelectPlan { if i != 0 { s.append(TokenType::TK_AND, None)?; } - expr.to_tokens_with_context(s, context)?; + expr.to_tokens(s, context)?; } } } @@ -471,7 +473,7 @@ impl ToTokens for SelectPlan { } impl ToTokens for DeletePlan { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, _: &C, @@ -500,7 +502,7 @@ impl ToTokens for DeletePlan { if i != 0 { s.append(TokenType::TK_AND, None)?; } - expr.to_tokens_with_context(s, context)?; + expr.to_tokens(s, context)?; } } @@ -533,7 +535,7 @@ impl ToTokens for DeletePlan { } impl ToTokens for UpdatePlan { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, _: &C, @@ -578,10 +580,10 @@ impl ToTokens for UpdatePlan { .map(|where_clause| where_clause.expr.clone()); iter.next() .expect("should not be empty") - .to_tokens_with_context(s, context)?; + .to_tokens(s, context)?; for expr in iter { s.append(TokenType::TK_AND, None)?; - expr.to_tokens_with_context(s, context)?; + expr.to_tokens(s, context)?; } } diff --git a/core/translate/main_loop.rs b/core/translate/main_loop.rs index 06d801705..6774c04d2 100644 --- a/core/translate/main_loop.rs +++ b/core/translate/main_loop.rs @@ -1,4 +1,4 @@ -use turso_parser::ast::SortOrder; +use turso_parser::ast::{fmt::ToTokens, SortOrder}; use std::sync::Arc; @@ -20,6 +20,7 @@ use crate::{ use super::{ aggregation::{translate_aggregation_step, AggArgumentSource}, + display::PlanContext, emitter::{OperationMode, TranslateCtx}, expr::{ translate_condition_expr, translate_expr, translate_expr_no_constant_opt, @@ -77,12 +78,17 @@ pub fn init_distinct(program: &mut ProgramBuilder, plan: &SelectPlan) -> Distinc .result_columns .iter() .enumerate() - .map(|(i, col)| IndexColumn { - name: col.expr.to_string(), - order: SortOrder::Asc, - pos_in_table: i, - collation: None, // FIXME: this should be determined based on the result column expression! - default: None, // FIXME: this should be determined based on the result column expression! + .map(|(i, col)| { + IndexColumn { + name: col + .expr + .displayer(&PlanContext(&[&plan.table_references])) + .to_string(), + order: SortOrder::Asc, + pos_in_table: i, + collation: None, // FIXME: this should be determined based on the result column expression! + default: None, // FIXME: this should be determined based on the result column expression! + } }) .collect(), unique: false, @@ -141,14 +147,18 @@ pub fn init_loop( agg.args.len() == 1, "DISTINCT aggregate functions must have exactly one argument" ); - let index_name = format!("distinct_agg_{}_{}", i, agg.args[0]); + let index_name = format!( + "distinct_agg_{}_{}", + i, + agg.args[0].displayer(&PlanContext(&[tables])) + ); let index = Arc::new(Index { name: index_name.clone(), table_name: String::new(), ephemeral: true, root_page: 0, columns: vec![IndexColumn { - name: agg.args[0].to_string(), + name: agg.args[0].displayer(&PlanContext(&[tables])).to_string(), order: SortOrder::Asc, pos_in_table: 0, collation: None, // FIXME: this should be inferred from the expression diff --git a/core/translate/optimizer/mod.rs b/core/translate/optimizer/mod.rs index 8502ca005..49b88c402 100644 --- a/core/translate/optimizer/mod.rs +++ b/core/translate/optimizer/mod.rs @@ -8,7 +8,7 @@ use join::{compute_best_join_order, BestJoinOrderResult}; use lift_common_subexpressions::lift_common_subexpressions_from_binary_or_terms; use order::{compute_order_target, plan_satisfies_order_target, EliminatesSortBy}; use turso_ext::{ConstraintInfo, ConstraintUsage}; -use turso_parser::ast::{self, fmt::ToTokens as _, Expr, SortOrder}; +use turso_parser::ast::{self, Expr, SortOrder}; use crate::{ parameters::PARAM_PREFIX, @@ -52,11 +52,7 @@ pub fn optimize_plan(plan: &mut Plan, schema: &Schema) -> Result<()> { } } // When debug tracing is enabled, print the optimized plan as a SQL string for debugging - tracing::debug!( - plan_sql = plan - .format_with_context(&crate::translate::display::PlanContext(&[])) - .unwrap() - ); + tracing::debug!(plan_sql = plan.to_string()); Ok(()) } diff --git a/core/translate/schema.rs b/core/translate/schema.rs index 46c60fdfc..03025651c 100644 --- a/core/translate/schema.rs +++ b/core/translate/schema.rs @@ -28,7 +28,6 @@ use crate::SymbolTable; use crate::{bail_parse_error, Result}; use turso_ext::VTabKind; -use turso_parser::ast::fmt::ToTokens; #[allow(clippy::too_many_arguments)] pub fn translate_create_table( @@ -509,14 +508,7 @@ enum PrimaryKeyDefinitionType<'a> { fn create_table_body_to_str(tbl_name: &ast::QualifiedName, body: &ast::CreateTableBody) -> String { let mut sql = String::new(); - sql.push_str( - format!( - "CREATE TABLE {} {}", - tbl_name.name.as_str(), - body.format().unwrap() - ) - .as_str(), - ); + sql.push_str(format!("CREATE TABLE {} {}", tbl_name.name.as_str(), body).as_str()); match body { ast::CreateTableBody::ColumnsAndConstraints { columns: _, diff --git a/core/translate/view.rs b/core/translate/view.rs index b339e8961..fcb12df01 100644 --- a/core/translate/view.rs +++ b/core/translate/view.rs @@ -6,7 +6,7 @@ use crate::vdbe::builder::{CursorType, ProgramBuilder}; use crate::vdbe::insn::{CmpInsFlags, Cookie, Insn}; use crate::{Connection, Result, SymbolTable}; use std::sync::Arc; -use turso_parser::ast::{self, fmt::ToTokens}; +use turso_parser::ast; /// Common logic for creating views (both regular and materialized) fn emit_create_view_program( @@ -109,11 +109,7 @@ pub fn translate_create_materialized_view( } fn create_materialized_view_to_str(view_name: &str, select_stmt: &ast::Select) -> String { - format!( - "CREATE MATERIALIZED VIEW {} AS {}", - view_name, - select_stmt.format().unwrap() - ) + format!("CREATE MATERIALIZED VIEW {view_name} AS {select_stmt}") } pub fn translate_create_view( @@ -148,11 +144,7 @@ pub fn translate_create_view( } fn create_view_to_str(view_name: &str, select_stmt: &ast::Select) -> String { - format!( - "CREATE VIEW {} AS {}", - view_name, - select_stmt.format().unwrap() - ) + format!("CREATE VIEW {view_name} AS {select_stmt}") } pub fn translate_drop_view( diff --git a/core/util.rs b/core/util.rs index 3adb733d5..80845c8c9 100644 --- a/core/util.rs +++ b/core/util.rs @@ -1261,7 +1261,7 @@ pub fn extract_view_columns(select_stmt: &ast::Select, schema: &Schema) -> Vec todo!(), @@ -4990,8 +4987,7 @@ pub fn op_function( idx_name, where_clause, } - .format() - .unwrap(), + .to_string(), ) } ast::Stmt::CreateTable { @@ -5037,8 +5033,7 @@ pub fn op_function( temporary, if_not_exists, } - .format() - .unwrap(), + .to_string(), ) } _ => todo!(), diff --git a/parser/src/ast.rs b/parser/src/ast.rs index d1b429a1e..0d12d2d0b 100644 --- a/parser/src/ast.rs +++ b/parser/src/ast.rs @@ -3,8 +3,6 @@ pub mod fmt; use strum_macros::{EnumIter, EnumString}; -use crate::ast::fmt::ToTokens; - /// `?` or `$` Prepared statement arg placeholder(s) #[derive(Default)] pub struct ParameterInfo { @@ -931,13 +929,6 @@ pub struct QualifiedName { pub alias: Option, // FIXME restrict alias usage (fullname vs xfullname) } -impl std::fmt::Display for QualifiedName { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - use fmt::ToTokens as _; - self.to_fmt(f) - } -} - impl QualifiedName { /// Constructor pub fn single(name: Name) -> Self { @@ -1155,12 +1146,6 @@ pub enum SortOrder { Desc, } -impl core::fmt::Display for SortOrder { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.to_fmt(f) - } -} - /// `NULLS FIRST` or `NULLS LAST` #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] diff --git a/parser/src/ast/fmt.rs b/parser/src/ast/fmt.rs index 0e46cb680..4b774837e 100644 --- a/parser/src/ast/fmt.rs +++ b/parser/src/ast/fmt.rs @@ -4,67 +4,66 @@ use std::fmt::{self, Display, Formatter, Write}; use crate::ast::*; use crate::token::TokenType; use crate::token::TokenType::*; +use crate::Result; use crate::ast::TableInternalId; /// Context to be used in ToSqlString pub trait ToSqlContext { /// Given an id, get the table name + /// First Option indicates whether the table exists /// /// Currently not considering aliases - fn get_table_name(&self, id: TableInternalId) -> &str; + fn get_table_name(&self, _id: TableInternalId) -> Option<&str> { + None + } + /// Given a table id and a column index, get the column name - fn get_column_name(&self, table_id: TableInternalId, col_idx: usize) -> String; -} + /// First Option indicates whether the column exists + /// Second Option indicates whether the column has a name + fn get_column_name(&self, _table_id: TableInternalId, _col_idx: usize) -> Option> { + None + } -struct FmtTokenStream<'a, 'b> { - f: &'a mut Formatter<'b>, - spaced: bool, -} + // help function to handle missing table/column names + fn get_table_and_column_names( + &self, + table_id: TableInternalId, + col_idx: usize, + ) -> (String, String) { + let table_name = self + .get_table_name(table_id) + .map(|s| s.to_owned()) + .unwrap_or_else(|| format!("t{}", table_id.0)); -impl TokenStream for FmtTokenStream<'_, '_> { - type Error = fmt::Error; + let column_name = self + .get_column_name(table_id, col_idx) + .map(|opt| { + opt.map(|s| s.to_owned()) + .unwrap_or_else(|| format!("c{col_idx}")) + }) + .unwrap_or_else(|| format!("c{col_idx}")); - fn append(&mut self, ty: TokenType, value: Option<&str>) -> fmt::Result { - if !self.spaced { - match ty { - TK_COMMA | TK_SEMI | TK_RP | TK_DOT => {} - _ => { - self.f.write_char(' ')?; - self.spaced = true; - } - }; - } - if ty == TK_BLOB { - self.f.write_char('X')?; - self.f.write_char('\'')?; - if let Some(str) = value { - self.f.write_str(str)?; - } - return self.f.write_char('\''); - } else if let Some(str) = ty.as_str() { - self.f.write_str(str)?; - self.spaced = ty == TK_LP || ty == TK_DOT; // str should not be whitespace - } - if let Some(str) = value { - // trick for pretty-print - self.spaced = str.bytes().all(|b| b.is_ascii_whitespace()); - /*if !self.spaced { - self.f.write_char(' ')?; - }*/ - self.f.write_str(str) - } else { - Ok(()) - } + (table_name, column_name) } } -struct WriteTokenStream<'a, T: fmt::Write> { +pub struct WriteTokenStream<'a, T: Write> { write: &'a mut T, spaced: bool, } -impl TokenStream for WriteTokenStream<'_, T> { +impl<'a, T: Write> WriteTokenStream<'a, T> { + /// Create a new token stream writing to the specified writer + pub fn new(write: &'a mut T) -> Self { + Self { + write, + spaced: true, + } + } +} + +impl TokenStream for WriteTokenStream<'_, T> { type Error = fmt::Error; fn append(&mut self, ty: TokenType, value: Option<&str>) -> fmt::Result { @@ -77,45 +76,47 @@ impl TokenStream for WriteTokenStream<'_, T> { } }; } - if ty == TK_BLOB { - self.write.write_char('X')?; - self.write.write_char('\'')?; - if let Some(str) = value { - self.write.write_str(str)?; + + match (ty, ty.as_str(), value) { + (TK_BLOB, None, value) => { + self.write.write_char('X')?; + self.write.write_char('\'')?; + if let Some(str) = value { + self.write.write_str(str)?; + } + self.write.write_char('\'')?; + Ok(()) + } + (_, ty_str, value) => { + if let Some(str) = ty_str { + self.write.write_str(str)?; + self.spaced = ty == TK_LP || ty == TK_DOT; // str should not be whitespace + } + + if let Some(str) = value { + // trick for pretty-print + self.spaced = str.bytes().all(|b| b.is_ascii_whitespace()); + self.write.write_str(str)?; + } + + Ok(()) } - return self.write.write_char('\''); - } else if let Some(str) = ty.as_str() { - self.write.write_str(str)?; - self.spaced = ty == TK_LP || ty == TK_DOT; // str should not be whitespace - } - if let Some(str) = value { - // trick for pretty-print - self.spaced = str.bytes().all(|b| b.is_ascii_whitespace()); - self.write.write_str(str) - } else { - Ok(()) } } } -struct BlankContext; +pub struct BlankContext; -impl ToSqlContext for BlankContext { - fn get_column_name(&self, _table_id: crate::ast::TableInternalId, _col_idx: usize) -> String { - "".to_string() - } - - fn get_table_name(&self, _id: crate::ast::TableInternalId) -> &str { - "" - } -} +impl ToSqlContext for BlankContext {} /// Stream of token pub trait TokenStream { /// Potential error raised type Error; + /// Push token to this stream fn append(&mut self, ty: TokenType, value: Option<&str>) -> Result<(), Self::Error>; + /// Interspace iterator with commas fn comma(&mut self, items: I, context: &C) -> Result<(), Self::Error> where @@ -127,72 +128,82 @@ pub trait TokenStream { if i != 0 { self.append(TK_COMMA, None)?; } - item.to_tokens_with_context(self, context)?; + item.to_tokens(self, context)?; } Ok(()) } } +pub struct SqlDisplayer<'a, 'b, C: ToSqlContext, T: ToTokens> { + ctx: &'a C, + start_node: &'b T, +} + +impl<'a, 'b, C: ToSqlContext, T: ToTokens> SqlDisplayer<'a, 'b, C, T> { + /// Create a new displayer with the specified context and AST node + pub fn new(ctx: &'a C, start_node: &'b T) -> Self { + Self { ctx, start_node } + } +} + +impl<'a, 'b, C: ToSqlContext, T: ToTokens> Display for SqlDisplayer<'a, 'b, C, T> { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let mut stream = WriteTokenStream::new(f); + self.start_node.to_tokens(&mut stream, self.ctx) + } +} + /// Generate token(s) from AST node -pub trait ToTokens { +/// Also implements Display to make sure devs won't forget Display +pub trait ToTokens: Display { /// Send token(s) to the specified stream with context - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error>; - /// Send token(s) to the specified stream - fn to_tokens(&self, s: &mut S) -> Result<(), S::Error> { - self.to_tokens_with_context(s, &BlankContext) - } - - /// Format AST node - fn to_fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - self.to_fmt_with_context(f, &BlankContext) - } - - /// Format AST node with context - fn to_fmt_with_context( - &self, - f: &mut Formatter<'_>, - context: &C, - ) -> fmt::Result { - let mut s = FmtTokenStream { f, spaced: true }; - self.to_tokens_with_context(&mut s, context) - } - - /// Format AST node to string - fn format(&self) -> Result { - self.format_with_context(&BlankContext) - } - - /// Format AST node to string with context - fn format_with_context(&self, context: &C) -> Result { - let mut s = String::new(); - let mut w = WriteTokenStream { - write: &mut s, - spaced: true, - }; - - self.to_tokens_with_context(&mut w, context)?; - - Ok(s) + // Return displayer representation with context + fn displayer<'a, 'b, C: ToSqlContext>(&'b self, ctx: &'a C) -> SqlDisplayer<'a, 'b, C, Self> + where + Self: Sized, + { + SqlDisplayer::new(ctx, self) } } +macro_rules! impl_display_for_to_tokens { + ($struct:ty) => { + impl Display for $struct { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + self.displayer(&BlankContext).fmt(f) + } + } + }; +} + impl ToTokens for &T { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { - ToTokens::to_tokens_with_context(&**self, s, context) + ToTokens::to_tokens(&**self, s, context) + } +} + +impl ToTokens for Box { + fn to_tokens( + &self, + s: &mut S, + context: &C, + ) -> Result<(), S::Error> { + ToTokens::to_tokens(self.as_ref(), s, context) } } impl ToTokens for String { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, _: &C, @@ -201,8 +212,9 @@ impl ToTokens for String { } } +impl_display_for_to_tokens!(Cmd); impl ToTokens for Cmd { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -210,30 +222,25 @@ impl ToTokens for Cmd { match self { Self::Explain(stmt) => { s.append(TK_EXPLAIN, None)?; - stmt.to_tokens_with_context(s, context)?; + stmt.to_tokens(s, context)?; } Self::ExplainQueryPlan(stmt) => { s.append(TK_EXPLAIN, None)?; s.append(TK_QUERY, None)?; s.append(TK_PLAN, None)?; - stmt.to_tokens_with_context(s, context)?; + stmt.to_tokens(s, context)?; } Self::Stmt(stmt) => { - stmt.to_tokens_with_context(s, context)?; + stmt.to_tokens(s, context)?; } } s.append(TK_SEMI, None) } } -impl Display for Cmd { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - self.to_fmt(f) - } -} - +impl_display_for_to_tokens!(Stmt); impl ToTokens for Stmt { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -242,35 +249,35 @@ impl ToTokens for Stmt { Self::AlterTable(AlterTable { name, body }) => { s.append(TK_ALTER, None)?; s.append(TK_TABLE, None)?; - name.to_tokens_with_context(s, context)?; - body.to_tokens_with_context(s, context) + name.to_tokens(s, context)?; + body.to_tokens(s, context) } Self::Analyze { name } => { s.append(TK_ANALYZE, None)?; if let Some(name) = name { - name.to_tokens_with_context(s, context)?; + name.to_tokens(s, context)?; } Ok(()) } Self::Attach { expr, db_name, key } => { s.append(TK_ATTACH, None)?; - expr.to_tokens_with_context(s, context)?; + expr.to_tokens(s, context)?; s.append(TK_AS, None)?; - db_name.to_tokens_with_context(s, context)?; + db_name.to_tokens(s, context)?; if let Some(key) = key { s.append(TK_KEY, None)?; - key.to_tokens_with_context(s, context)?; + key.to_tokens(s, context)?; } Ok(()) } Self::Begin { typ, name } => { s.append(TK_BEGIN, None)?; if let Some(typ) = typ { - typ.to_tokens_with_context(s, context)?; + typ.to_tokens(s, context)?; } if let Some(name) = name { s.append(TK_TRANSACTION, None)?; - name.to_tokens_with_context(s, context)?; + name.to_tokens(s, context)?; } Ok(()) } @@ -278,7 +285,7 @@ impl ToTokens for Stmt { s.append(TK_COMMIT, None)?; if let Some(name) = name { s.append(TK_TRANSACTION, None)?; - name.to_tokens_with_context(s, context)?; + name.to_tokens(s, context)?; } Ok(()) } @@ -300,15 +307,15 @@ impl ToTokens for Stmt { s.append(TK_NOT, None)?; s.append(TK_EXISTS, None)?; } - idx_name.to_tokens_with_context(s, context)?; + idx_name.to_tokens(s, context)?; s.append(TK_ON, None)?; - tbl_name.to_tokens_with_context(s, context)?; + tbl_name.to_tokens(s, context)?; s.append(TK_LP, None)?; comma(columns, s, context)?; s.append(TK_RP, None)?; if let Some(where_clause) = where_clause { s.append(TK_WHERE, None)?; - where_clause.to_tokens_with_context(s, context)?; + where_clause.to_tokens(s, context)?; } Ok(()) } @@ -328,8 +335,8 @@ impl ToTokens for Stmt { s.append(TK_NOT, None)?; s.append(TK_EXISTS, None)?; } - tbl_name.to_tokens_with_context(s, context)?; - body.to_tokens_with_context(s, context) + tbl_name.to_tokens(s, context)?; + body.to_tokens(s, context) } Self::CreateTrigger { temporary, @@ -352,13 +359,13 @@ impl ToTokens for Stmt { s.append(TK_NOT, None)?; s.append(TK_EXISTS, None)?; } - trigger_name.to_tokens_with_context(s, context)?; + trigger_name.to_tokens(s, context)?; if let Some(time) = time { - time.to_tokens_with_context(s, context)?; + time.to_tokens(s, context)?; } - event.to_tokens_with_context(s, context)?; + event.to_tokens(s, context)?; s.append(TK_ON, None)?; - tbl_name.to_tokens_with_context(s, context)?; + tbl_name.to_tokens(s, context)?; if *for_each_row { s.append(TK_FOR, None)?; s.append(TK_EACH, None)?; @@ -366,11 +373,11 @@ impl ToTokens for Stmt { } if let Some(when_clause) = when_clause { s.append(TK_WHEN, None)?; - when_clause.to_tokens_with_context(s, context)?; + when_clause.to_tokens(s, context)?; } s.append(TK_BEGIN, Some("\n"))?; for command in commands { - command.to_tokens_with_context(s, context)?; + command.to_tokens(s, context)?; s.append(TK_SEMI, Some("\n"))?; } s.append(TK_END, None) @@ -392,14 +399,14 @@ impl ToTokens for Stmt { s.append(TK_NOT, None)?; s.append(TK_EXISTS, None)?; } - view_name.to_tokens_with_context(s, context)?; + view_name.to_tokens(s, context)?; if !columns.is_empty() { s.append(TK_LP, None)?; comma(columns, s, context)?; s.append(TK_RP, None)?; } s.append(TK_AS, None)?; - select.to_tokens_with_context(s, context) + select.to_tokens(s, context) } Self::CreateMaterializedView { if_not_exists, @@ -415,14 +422,14 @@ impl ToTokens for Stmt { s.append(TK_NOT, None)?; s.append(TK_EXISTS, None)?; } - view_name.to_tokens_with_context(s, context)?; + view_name.to_tokens(s, context)?; if !columns.is_empty() { s.append(TK_LP, None)?; comma(columns, s, context)?; s.append(TK_RP, None)?; } s.append(TK_AS, None)?; - select.to_tokens_with_context(s, context) + select.to_tokens(s, context) } Self::CreateVirtualTable(CreateVirtualTable { if_not_exists, @@ -438,9 +445,9 @@ impl ToTokens for Stmt { s.append(TK_NOT, None)?; s.append(TK_EXISTS, None)?; } - tbl_name.to_tokens_with_context(s, context)?; + tbl_name.to_tokens(s, context)?; s.append(TK_USING, None)?; - module_name.to_tokens_with_context(s, context)?; + module_name.to_tokens(s, context)?; s.append(TK_LP, None)?; if !args.is_empty() { comma(args, s, context)?; @@ -457,17 +464,17 @@ impl ToTokens for Stmt { limit, } => { if let Some(with) = with { - with.to_tokens_with_context(s, context)?; + with.to_tokens(s, context)?; } s.append(TK_DELETE, None)?; s.append(TK_FROM, None)?; - tbl_name.to_tokens_with_context(s, context)?; + tbl_name.to_tokens(s, context)?; if let Some(indexed) = indexed { - indexed.to_tokens_with_context(s, context)?; + indexed.to_tokens(s, context)?; } if let Some(where_clause) = where_clause { s.append(TK_WHERE, None)?; - where_clause.to_tokens_with_context(s, context)?; + where_clause.to_tokens(s, context)?; } if !returning.is_empty() { s.append(TK_RETURNING, None)?; @@ -479,13 +486,13 @@ impl ToTokens for Stmt { comma(order_by, s, context)?; } if let Some(limit) = limit { - limit.to_tokens_with_context(s, context)?; + limit.to_tokens(s, context)?; } Ok(()) } Self::Detach { name } => { s.append(TK_DETACH, None)?; - name.to_tokens_with_context(s, context) + name.to_tokens(s, context) } Self::DropIndex { if_exists, @@ -497,7 +504,7 @@ impl ToTokens for Stmt { s.append(TK_IF, None)?; s.append(TK_EXISTS, None)?; } - idx_name.to_tokens_with_context(s, context) + idx_name.to_tokens(s, context) } Self::DropTable { if_exists, @@ -509,7 +516,7 @@ impl ToTokens for Stmt { s.append(TK_IF, None)?; s.append(TK_EXISTS, None)?; } - tbl_name.to_tokens_with_context(s, context) + tbl_name.to_tokens(s, context) } Self::DropTrigger { if_exists, @@ -521,7 +528,7 @@ impl ToTokens for Stmt { s.append(TK_IF, None)?; s.append(TK_EXISTS, None)?; } - trigger_name.to_tokens_with_context(s, context) + trigger_name.to_tokens(s, context) } Self::DropView { if_exists, @@ -533,7 +540,7 @@ impl ToTokens for Stmt { s.append(TK_IF, None)?; s.append(TK_EXISTS, None)?; } - view_name.to_tokens_with_context(s, context) + view_name.to_tokens(s, context) } Self::Insert { with, @@ -544,7 +551,7 @@ impl ToTokens for Stmt { returning, } => { if let Some(with) = with { - with.to_tokens_with_context(s, context)?; + with.to_tokens(s, context)?; } if let Some(ResolveType::Replace) = or_conflict { s.append(TK_REPLACE, None)?; @@ -552,17 +559,17 @@ impl ToTokens for Stmt { s.append(TK_INSERT, None)?; if let Some(or_conflict) = or_conflict { s.append(TK_OR, None)?; - or_conflict.to_tokens_with_context(s, context)?; + or_conflict.to_tokens(s, context)?; } } s.append(TK_INTO, None)?; - tbl_name.to_tokens_with_context(s, context)?; + tbl_name.to_tokens(s, context)?; if !columns.is_empty() { s.append(TK_LP, None)?; comma(columns, s, context)?; s.append(TK_RP, None)?; } - body.to_tokens_with_context(s, context)?; + body.to_tokens(s, context)?; if !returning.is_empty() { s.append(TK_RETURNING, None)?; comma(returning, s, context)?; @@ -571,22 +578,22 @@ impl ToTokens for Stmt { } Self::Pragma { name, body } => { s.append(TK_PRAGMA, None)?; - name.to_tokens_with_context(s, context)?; + name.to_tokens(s, context)?; if let Some(body) = body { - body.to_tokens_with_context(s, context)?; + body.to_tokens(s, context)?; } Ok(()) } Self::Reindex { name } => { s.append(TK_REINDEX, None)?; if let Some(name) = name { - name.to_tokens_with_context(s, context)?; + name.to_tokens(s, context)?; } Ok(()) } Self::Release { name } => { s.append(TK_RELEASE, None)?; - name.to_tokens_with_context(s, context) + name.to_tokens(s, context) } Self::Rollback { tx_name, @@ -595,19 +602,19 @@ impl ToTokens for Stmt { s.append(TK_ROLLBACK, None)?; if let Some(tx_name) = tx_name { s.append(TK_TRANSACTION, None)?; - tx_name.to_tokens_with_context(s, context)?; + tx_name.to_tokens(s, context)?; } if let Some(savepoint_name) = savepoint_name { s.append(TK_TO, None)?; - savepoint_name.to_tokens_with_context(s, context)?; + savepoint_name.to_tokens(s, context)?; } Ok(()) } Self::Savepoint { name } => { s.append(TK_SAVEPOINT, None)?; - name.to_tokens_with_context(s, context) + name.to_tokens(s, context) } - Self::Select(select) => select.to_tokens_with_context(s, context), + Self::Select(select) => select.to_tokens(s, context), Self::Update(Update { with, or_conflict, @@ -621,26 +628,26 @@ impl ToTokens for Stmt { limit, }) => { if let Some(with) = with { - with.to_tokens_with_context(s, context)?; + with.to_tokens(s, context)?; } s.append(TK_UPDATE, None)?; if let Some(or_conflict) = or_conflict { s.append(TK_OR, None)?; - or_conflict.to_tokens_with_context(s, context)?; + or_conflict.to_tokens(s, context)?; } - tbl_name.to_tokens_with_context(s, context)?; + tbl_name.to_tokens(s, context)?; if let Some(indexed) = indexed { - indexed.to_tokens_with_context(s, context)?; + indexed.to_tokens(s, context)?; } s.append(TK_SET, None)?; comma(sets, s, context)?; if let Some(from) = from { s.append(TK_FROM, None)?; - from.to_tokens_with_context(s, context)?; + from.to_tokens(s, context)?; } if let Some(where_clause) = where_clause { s.append(TK_WHERE, None)?; - where_clause.to_tokens_with_context(s, context)?; + where_clause.to_tokens(s, context)?; } if !returning.is_empty() { s.append(TK_RETURNING, None)?; @@ -652,18 +659,18 @@ impl ToTokens for Stmt { comma(order_by, s, context)?; } if let Some(limit) = limit { - limit.to_tokens_with_context(s, context)?; + limit.to_tokens(s, context)?; } Ok(()) } Self::Vacuum { name, into } => { s.append(TK_VACUUM, None)?; if let Some(ref name) = name { - name.to_tokens_with_context(s, context)?; + name.to_tokens(s, context)?; } if let Some(ref into) = into { s.append(TK_INTO, None)?; - into.to_tokens_with_context(s, context)?; + into.to_tokens(s, context)?; } Ok(()) } @@ -671,18 +678,9 @@ impl ToTokens for Stmt { } } -impl ToTokens for Box { - fn to_tokens_with_context( - &self, - s: &mut S, - context: &C, - ) -> Result<(), S::Error> { - self.as_ref().to_tokens_with_context(s, context) - } -} - +impl_display_for_to_tokens!(Expr); impl ToTokens for Expr { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -694,19 +692,19 @@ impl ToTokens for Expr { start, end, } => { - lhs.to_tokens_with_context(s, context)?; + lhs.to_tokens(s, context)?; if *not { s.append(TK_NOT, None)?; } s.append(TK_BETWEEN, None)?; - start.to_tokens_with_context(s, context)?; + start.to_tokens(s, context)?; s.append(TK_AND, None)?; - end.to_tokens_with_context(s, context) + end.to_tokens(s, context) } Self::Binary(lhs, op, rhs) => { - lhs.to_tokens_with_context(s, context)?; - op.to_tokens_with_context(s, context)?; - rhs.to_tokens_with_context(s, context) + lhs.to_tokens(s, context)?; + op.to_tokens(s, context)?; + rhs.to_tokens(s, context) } Self::Register(reg) => { // This is for internal use only, not part of SQL syntax @@ -720,46 +718,46 @@ impl ToTokens for Expr { } => { s.append(TK_CASE, None)?; if let Some(ref base) = base { - base.to_tokens_with_context(s, context)?; + base.to_tokens(s, context)?; } for (when, then) in when_then_pairs { s.append(TK_WHEN, None)?; - when.to_tokens_with_context(s, context)?; + when.to_tokens(s, context)?; s.append(TK_THEN, None)?; - then.to_tokens_with_context(s, context)?; + then.to_tokens(s, context)?; } if let Some(ref else_expr) = else_expr { s.append(TK_ELSE, None)?; - else_expr.to_tokens_with_context(s, context)?; + else_expr.to_tokens(s, context)?; } s.append(TK_END, None) } Self::Cast { expr, type_name } => { s.append(TK_CAST, None)?; s.append(TK_LP, None)?; - expr.to_tokens_with_context(s, context)?; + expr.to_tokens(s, context)?; s.append(TK_AS, None)?; if let Some(ref type_name) = type_name { - type_name.to_tokens_with_context(s, context)?; + type_name.to_tokens(s, context)?; } s.append(TK_RP, None) } Self::Collate(expr, collation) => { - expr.to_tokens_with_context(s, context)?; + expr.to_tokens(s, context)?; s.append(TK_COLLATE, None)?; double_quote(collation.as_str(), s) } Self::DoublyQualified(db_name, tbl_name, col_name) => { - db_name.to_tokens_with_context(s, context)?; + db_name.to_tokens(s, context)?; s.append(TK_DOT, None)?; - tbl_name.to_tokens_with_context(s, context)?; + tbl_name.to_tokens(s, context)?; s.append(TK_DOT, None)?; - col_name.to_tokens_with_context(s, context) + col_name.to_tokens(s, context) } Self::Exists(subquery) => { s.append(TK_EXISTS, None)?; s.append(TK_LP, None)?; - subquery.to_tokens_with_context(s, context)?; + subquery.to_tokens(s, context)?; s.append(TK_RP, None) } Self::FunctionCall { @@ -769,10 +767,10 @@ impl ToTokens for Expr { order_by, filter_over, } => { - name.to_tokens_with_context(s, context)?; + name.to_tokens(s, context)?; s.append(TK_LP, None)?; if let Some(distinctness) = distinctness { - distinctness.to_tokens_with_context(s, context)?; + distinctness.to_tokens(s, context)?; } if !args.is_empty() { comma(args, s, context)?; @@ -783,25 +781,26 @@ impl ToTokens for Expr { comma(order_by, s, context)?; } s.append(TK_RP, None)?; - filter_over.to_tokens_with_context(s, context)?; + filter_over.to_tokens(s, context)?; Ok(()) } Self::FunctionCallStar { name, filter_over } => { - name.to_tokens_with_context(s, context)?; + name.to_tokens(s, context)?; s.append(TK_LP, None)?; s.append(TK_STAR, None)?; s.append(TK_RP, None)?; - filter_over.to_tokens_with_context(s, context)?; + filter_over.to_tokens(s, context)?; Ok(()) } - Self::Id(id) => id.to_tokens_with_context(s, context), + Self::Id(id) => id.to_tokens(s, context), Self::Column { table, column, .. } => { - s.append(TK_ID, Some(context.get_table_name(*table)))?; + let (tbl_name, col_name) = context.get_table_and_column_names(*table, *column); + s.append(TK_ID, Some(tbl_name.as_ref()))?; s.append(TK_DOT, None)?; - s.append(TK_ID, Some(&context.get_column_name(*table, *column))) + s.append(TK_ID, Some(col_name.as_ref())) } Self::InList { lhs, not, rhs } => { - lhs.to_tokens_with_context(s, context)?; + lhs.to_tokens(s, context)?; if *not { s.append(TK_NOT, None)?; } @@ -813,13 +812,13 @@ impl ToTokens for Expr { s.append(TK_RP, None) } Self::InSelect { lhs, not, rhs } => { - lhs.to_tokens_with_context(s, context)?; + lhs.to_tokens(s, context)?; if *not { s.append(TK_NOT, None)?; } s.append(TK_IN, None)?; s.append(TK_LP, None)?; - rhs.to_tokens_with_context(s, context)?; + rhs.to_tokens(s, context)?; s.append(TK_RP, None) } Self::InTable { @@ -828,12 +827,12 @@ impl ToTokens for Expr { rhs, args, } => { - lhs.to_tokens_with_context(s, context)?; + lhs.to_tokens(s, context)?; if *not { s.append(TK_NOT, None)?; } s.append(TK_IN, None)?; - rhs.to_tokens_with_context(s, context)?; + rhs.to_tokens(s, context)?; if !args.is_empty() { s.append(TK_LP, None)?; comma(args, s, context)?; @@ -842,7 +841,7 @@ impl ToTokens for Expr { Ok(()) } Self::IsNull(sub_expr) => { - sub_expr.to_tokens_with_context(s, context)?; + sub_expr.to_tokens(s, context)?; s.append(TK_ISNULL, None) } Self::Like { @@ -852,22 +851,22 @@ impl ToTokens for Expr { rhs, escape, } => { - lhs.to_tokens_with_context(s, context)?; + lhs.to_tokens(s, context)?; if *not { s.append(TK_NOT, None)?; } - op.to_tokens_with_context(s, context)?; - rhs.to_tokens_with_context(s, context)?; + op.to_tokens(s, context)?; + rhs.to_tokens(s, context)?; if let Some(escape) = escape { s.append(TK_ESCAPE, None)?; - escape.to_tokens_with_context(s, context)?; + escape.to_tokens(s, context)?; } Ok(()) } - Self::Literal(lit) => lit.to_tokens_with_context(s, context), - Self::Name(name) => name.to_tokens_with_context(s, context), + Self::Literal(lit) => lit.to_tokens(s, context), + Self::Name(name) => name.to_tokens(s, context), Self::NotNull(sub_expr) => { - sub_expr.to_tokens_with_context(s, context)?; + sub_expr.to_tokens(s, context)?; s.append(TK_NOTNULL, None) } Self::Parenthesized(exprs) => { @@ -876,29 +875,29 @@ impl ToTokens for Expr { s.append(TK_RP, None) } Self::Qualified(qualifier, qualified) => { - qualifier.to_tokens_with_context(s, context)?; + qualifier.to_tokens(s, context)?; s.append(TK_DOT, None)?; - qualified.to_tokens_with_context(s, context) + qualified.to_tokens(s, context) } Self::Raise(rt, err) => { s.append(TK_RAISE, None)?; s.append(TK_LP, None)?; - rt.to_tokens_with_context(s, context)?; + rt.to_tokens(s, context)?; if let Some(err) = err { s.append(TK_COMMA, None)?; - err.to_tokens_with_context(s, context)?; + err.to_tokens(s, context)?; } s.append(TK_RP, None) } Self::RowId { .. } => Ok(()), Self::Subquery(query) => { s.append(TK_LP, None)?; - query.to_tokens_with_context(s, context)?; + query.to_tokens(s, context)?; s.append(TK_RP, None) } Self::Unary(op, sub_expr) => { - op.to_tokens_with_context(s, context)?; - sub_expr.to_tokens_with_context(s, context) + op.to_tokens(s, context)?; + sub_expr.to_tokens(s, context) } Self::Variable(var) => match var.chars().next() { Some(c) if c == '$' || c == '@' || c == '#' || c == ':' => { @@ -911,14 +910,9 @@ impl ToTokens for Expr { } } -impl Display for Expr { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - self.to_fmt(f) - } -} - +impl_display_for_to_tokens!(Literal); impl ToTokens for Literal { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, _: &C, @@ -936,8 +930,9 @@ impl ToTokens for Literal { } } +impl_display_for_to_tokens!(LikeOperator); impl ToTokens for LikeOperator { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, _: &C, @@ -954,8 +949,9 @@ impl ToTokens for LikeOperator { } } +impl_display_for_to_tokens!(Operator); impl ToTokens for Operator { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, _: &C, @@ -991,8 +987,9 @@ impl ToTokens for Operator { } } +impl_display_for_to_tokens!(UnaryOperator); impl ToTokens for UnaryOperator { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, _: &C, @@ -1009,55 +1006,59 @@ impl ToTokens for UnaryOperator { } } +impl_display_for_to_tokens!(Select); impl ToTokens for Select { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { if let Some(ref with) = self.with { - with.to_tokens_with_context(s, context)?; + with.to_tokens(s, context)?; } - self.body.to_tokens_with_context(s, context)?; + self.body.to_tokens(s, context)?; if !self.order_by.is_empty() { s.append(TK_ORDER, None)?; s.append(TK_BY, None)?; comma(&self.order_by, s, context)?; } if let Some(ref limit) = self.limit { - limit.to_tokens_with_context(s, context)?; + limit.to_tokens(s, context)?; } Ok(()) } } +impl_display_for_to_tokens!(SelectBody); impl ToTokens for SelectBody { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { - self.select.to_tokens_with_context(s, context)?; + self.select.to_tokens(s, context)?; for compound in &self.compounds { - compound.to_tokens_with_context(s, context)?; + compound.to_tokens(s, context)?; } Ok(()) } } +impl_display_for_to_tokens!(CompoundSelect); impl ToTokens for CompoundSelect { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { - self.operator.to_tokens_with_context(s, context)?; - self.select.to_tokens_with_context(s, context) + self.operator.to_tokens(s, context)?; + self.select.to_tokens(s, context) } } +impl_display_for_to_tokens!(CompoundOperator); impl ToTokens for CompoundOperator { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, _: &C, @@ -1074,14 +1075,9 @@ impl ToTokens for CompoundOperator { } } -impl Display for CompoundOperator { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - self.to_fmt(f) - } -} - +impl_display_for_to_tokens!(OneSelect); impl ToTokens for OneSelect { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -1097,19 +1093,19 @@ impl ToTokens for OneSelect { } => { s.append(TK_SELECT, None)?; if let Some(ref distinctness) = distinctness { - distinctness.to_tokens_with_context(s, context)?; + distinctness.to_tokens(s, context)?; } comma(columns, s, context)?; if let Some(ref from) = from { s.append(TK_FROM, None)?; - from.to_tokens_with_context(s, context)?; + from.to_tokens(s, context)?; } if let Some(ref where_clause) = where_clause { s.append(TK_WHERE, None)?; - where_clause.to_tokens_with_context(s, context)?; + where_clause.to_tokens(s, context)?; } if let Some(ref group_by) = group_by { - group_by.to_tokens_with_context(s, context)?; + group_by.to_tokens(s, context)?; } if !window_clause.is_empty() { s.append(TK_WINDOW, None)?; @@ -1134,23 +1130,25 @@ impl ToTokens for OneSelect { } } +impl_display_for_to_tokens!(FromClause); impl ToTokens for FromClause { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { - self.select.as_ref().to_tokens_with_context(s, context)?; + self.select.as_ref().to_tokens(s, context)?; for join in &self.joins { - join.to_tokens_with_context(s, context)?; + join.to_tokens(s, context)?; } Ok(()) } } +impl_display_for_to_tokens!(Distinctness); impl ToTokens for Distinctness { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, _: &C, @@ -1165,23 +1163,24 @@ impl ToTokens for Distinctness { } } +impl_display_for_to_tokens!(ResultColumn); impl ToTokens for ResultColumn { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { match self { Self::Expr(expr, alias) => { - expr.to_tokens_with_context(s, context)?; + expr.to_tokens(s, context)?; if let Some(alias) = alias { - alias.to_tokens_with_context(s, context)?; + alias.to_tokens(s, context)?; } Ok(()) } Self::Star => s.append(TK_STAR, None), Self::TableStar(tbl_name) => { - tbl_name.to_tokens_with_context(s, context)?; + tbl_name.to_tokens(s, context)?; s.append(TK_DOT, None)?; s.append(TK_STAR, None) } @@ -1189,8 +1188,9 @@ impl ToTokens for ResultColumn { } } +impl_display_for_to_tokens!(As); impl ToTokens for As { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -1198,70 +1198,72 @@ impl ToTokens for As { match self { Self::As(ref name) => { s.append(TK_AS, None)?; - name.to_tokens_with_context(s, context) + name.to_tokens(s, context) } - Self::Elided(ref name) => name.to_tokens_with_context(s, context), + Self::Elided(ref name) => name.to_tokens(s, context), } } } +impl_display_for_to_tokens!(JoinedSelectTable); impl ToTokens for JoinedSelectTable { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { - self.operator.to_tokens_with_context(s, context)?; - self.table.to_tokens_with_context(s, context)?; + self.operator.to_tokens(s, context)?; + self.table.to_tokens(s, context)?; if let Some(ref constraint) = self.constraint { - constraint.to_tokens_with_context(s, context)?; + constraint.to_tokens(s, context)?; } Ok(()) } } +impl_display_for_to_tokens!(SelectTable); impl ToTokens for SelectTable { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { match self { Self::Table(name, alias, indexed) => { - name.to_tokens_with_context(s, context)?; + name.to_tokens(s, context)?; if let Some(alias) = alias { - alias.to_tokens_with_context(s, context)?; + alias.to_tokens(s, context)?; } if let Some(indexed) = indexed { - indexed.to_tokens_with_context(s, context)?; + indexed.to_tokens(s, context)?; } Ok(()) } Self::TableCall(name, exprs, alias) => { - name.to_tokens_with_context(s, context)?; + name.to_tokens(s, context)?; s.append(TK_LP, None)?; comma(exprs, s, context)?; s.append(TK_RP, None)?; if let Some(alias) = alias { - alias.to_tokens_with_context(s, context)?; + alias.to_tokens(s, context)?; } Ok(()) } Self::Select(select, alias) => { s.append(TK_LP, None)?; - select.to_tokens_with_context(s, context)?; + select.to_tokens(s, context)?; s.append(TK_RP, None)?; if let Some(alias) = alias { - alias.to_tokens_with_context(s, context)?; + alias.to_tokens(s, context)?; } Ok(()) } Self::Sub(from, alias) => { s.append(TK_LP, None)?; - from.to_tokens_with_context(s, context)?; + from.to_tokens(s, context)?; s.append(TK_RP, None)?; if let Some(alias) = alias { - alias.to_tokens_with_context(s, context)?; + alias.to_tokens(s, context)?; } Ok(()) } @@ -1269,8 +1271,9 @@ impl ToTokens for SelectTable { } } +impl_display_for_to_tokens!(JoinOperator); impl ToTokens for JoinOperator { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -1279,7 +1282,7 @@ impl ToTokens for JoinOperator { Self::Comma => s.append(TK_COMMA, None), Self::TypedJoin(join_type) => { if let Some(ref join_type) = join_type { - join_type.to_tokens_with_context(s, context)?; + join_type.to_tokens(s, context)?; } s.append(TK_JOIN, None) } @@ -1287,8 +1290,9 @@ impl ToTokens for JoinOperator { } } +impl_display_for_to_tokens!(JoinType); impl ToTokens for JoinType { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, _: &C, @@ -1319,8 +1323,9 @@ impl ToTokens for JoinType { } } +impl_display_for_to_tokens!(JoinConstraint); impl ToTokens for JoinConstraint { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -1328,7 +1333,7 @@ impl ToTokens for JoinConstraint { match self { Self::On(expr) => { s.append(TK_ON, None)?; - expr.to_tokens_with_context(s, context) + expr.to_tokens(s, context) } Self::Using(col_names) => { s.append(TK_USING, None)?; @@ -1340,8 +1345,9 @@ impl ToTokens for JoinConstraint { } } +impl_display_for_to_tokens!(GroupBy); impl ToTokens for GroupBy { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -1351,14 +1357,15 @@ impl ToTokens for GroupBy { comma(&self.exprs, s, context)?; if let Some(ref having) = self.having { s.append(TK_HAVING, None)?; - having.to_tokens_with_context(s, context)?; + having.to_tokens(s, context)?; } Ok(()) } } +impl_display_for_to_tokens!(Name); impl ToTokens for Name { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, _: &C, @@ -1367,33 +1374,29 @@ impl ToTokens for Name { } } -impl Display for Name { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - self.to_fmt(f) - } -} - +impl_display_for_to_tokens!(QualifiedName); impl ToTokens for QualifiedName { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { if let Some(ref db_name) = self.db_name { - db_name.to_tokens_with_context(s, context)?; + db_name.to_tokens(s, context)?; s.append(TK_DOT, None)?; } - self.name.to_tokens_with_context(s, context)?; + self.name.to_tokens(s, context)?; if let Some(ref alias) = self.alias { s.append(TK_AS, None)?; - alias.to_tokens_with_context(s, context)?; + alias.to_tokens(s, context)?; } Ok(()) } } +impl_display_for_to_tokens!(AlterTableBody); impl ToTokens for AlterTableBody { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -1402,38 +1405,39 @@ impl ToTokens for AlterTableBody { Self::RenameTo(name) => { s.append(TK_RENAME, None)?; s.append(TK_TO, None)?; - name.to_tokens_with_context(s, context) + name.to_tokens(s, context) } Self::AddColumn(def) => { s.append(TK_ADD, None)?; s.append(TK_COLUMNKW, None)?; - def.to_tokens_with_context(s, context) + def.to_tokens(s, context) } Self::AlterColumn { old, new } => { s.append(TK_ALTER, None)?; s.append(TK_COLUMNKW, None)?; - old.to_tokens_with_context(s, context)?; + old.to_tokens(s, context)?; s.append(TK_TO, None)?; - new.to_tokens_with_context(s, context) + new.to_tokens(s, context) } Self::RenameColumn { old, new } => { s.append(TK_RENAME, None)?; s.append(TK_COLUMNKW, None)?; - old.to_tokens_with_context(s, context)?; + old.to_tokens(s, context)?; s.append(TK_TO, None)?; - new.to_tokens_with_context(s, context) + new.to_tokens(s, context) } Self::DropColumn(name) => { s.append(TK_DROP, None)?; s.append(TK_COLUMNKW, None)?; - name.to_tokens_with_context(s, context) + name.to_tokens(s, context) } } } } +impl_display_for_to_tokens!(CreateTableBody); impl ToTokens for CreateTableBody { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -1462,45 +1466,48 @@ impl ToTokens for CreateTableBody { } Self::AsSelect(select) => { s.append(TK_AS, None)?; - select.to_tokens_with_context(s, context) + select.to_tokens(s, context) } } } } +impl_display_for_to_tokens!(ColumnDefinition); impl ToTokens for ColumnDefinition { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { - self.col_name.to_tokens_with_context(s, context)?; + self.col_name.to_tokens(s, context)?; if let Some(ref col_type) = self.col_type { - col_type.to_tokens_with_context(s, context)?; + col_type.to_tokens(s, context)?; } for constraint in &self.constraints { - constraint.to_tokens_with_context(s, context)?; + constraint.to_tokens(s, context)?; } Ok(()) } } +impl_display_for_to_tokens!(NamedColumnConstraint); impl ToTokens for NamedColumnConstraint { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { if let Some(ref name) = self.name { s.append(TK_CONSTRAINT, None)?; - name.to_tokens_with_context(s, context)?; + name.to_tokens(s, context)?; } - self.constraint.to_tokens_with_context(s, context) + self.constraint.to_tokens(s, context) } } +impl_display_for_to_tokens!(ColumnConstraint); impl ToTokens for ColumnConstraint { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -1514,12 +1521,12 @@ impl ToTokens for ColumnConstraint { s.append(TK_PRIMARY, None)?; s.append(TK_KEY, None)?; if let Some(order) = order { - order.to_tokens_with_context(s, context)?; + order.to_tokens(s, context)?; } if let Some(conflict_clause) = conflict_clause { s.append(TK_ON, None)?; s.append(TK_CONFLICT, None)?; - conflict_clause.to_tokens_with_context(s, context)?; + conflict_clause.to_tokens(s, context)?; } if *auto_increment { s.append(TK_AUTOINCR, None)?; @@ -1537,7 +1544,7 @@ impl ToTokens for ColumnConstraint { if let Some(conflict_clause) = conflict_clause { s.append(TK_ON, None)?; s.append(TK_CONFLICT, None)?; - conflict_clause.to_tokens_with_context(s, context)?; + conflict_clause.to_tokens(s, context)?; } Ok(()) } @@ -1546,42 +1553,42 @@ impl ToTokens for ColumnConstraint { if let Some(conflict_clause) = conflict_clause { s.append(TK_ON, None)?; s.append(TK_CONFLICT, None)?; - conflict_clause.to_tokens_with_context(s, context)?; + conflict_clause.to_tokens(s, context)?; } Ok(()) } Self::Check(expr) => { s.append(TK_CHECK, None)?; s.append(TK_LP, None)?; - expr.to_tokens_with_context(s, context)?; + expr.to_tokens(s, context)?; s.append(TK_RP, None) } Self::Default(expr) => { s.append(TK_DEFAULT, None)?; - expr.to_tokens_with_context(s, context) + expr.to_tokens(s, context) } Self::Collate { collation_name } => { s.append(TK_COLLATE, None)?; - collation_name.to_tokens_with_context(s, context) + collation_name.to_tokens(s, context) } Self::ForeignKey { clause, deref_clause, } => { s.append(TK_REFERENCES, None)?; - clause.to_tokens_with_context(s, context)?; + clause.to_tokens(s, context)?; if let Some(deref_clause) = deref_clause { - deref_clause.to_tokens_with_context(s, context)?; + deref_clause.to_tokens(s, context)?; } Ok(()) } Self::Generated { expr, typ } => { s.append(TK_AS, None)?; s.append(TK_LP, None)?; - expr.to_tokens_with_context(s, context)?; + expr.to_tokens(s, context)?; s.append(TK_RP, None)?; if let Some(typ) = typ { - typ.to_tokens_with_context(s, context)?; + typ.to_tokens(s, context)?; } Ok(()) } @@ -1589,22 +1596,24 @@ impl ToTokens for ColumnConstraint { } } +impl_display_for_to_tokens!(NamedTableConstraint); impl ToTokens for NamedTableConstraint { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { if let Some(ref name) = self.name { s.append(TK_CONSTRAINT, None)?; - name.to_tokens_with_context(s, context)?; + name.to_tokens(s, context)?; } - self.constraint.to_tokens_with_context(s, context) + self.constraint.to_tokens(s, context) } } +impl_display_for_to_tokens!(TableConstraint); impl ToTokens for TableConstraint { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -1626,7 +1635,7 @@ impl ToTokens for TableConstraint { if let Some(conflict_clause) = conflict_clause { s.append(TK_ON, None)?; s.append(TK_CONFLICT, None)?; - conflict_clause.to_tokens_with_context(s, context)?; + conflict_clause.to_tokens(s, context)?; } Ok(()) } @@ -1641,14 +1650,14 @@ impl ToTokens for TableConstraint { if let Some(conflict_clause) = conflict_clause { s.append(TK_ON, None)?; s.append(TK_CONFLICT, None)?; - conflict_clause.to_tokens_with_context(s, context)?; + conflict_clause.to_tokens(s, context)?; } Ok(()) } Self::Check(expr) => { s.append(TK_CHECK, None)?; s.append(TK_LP, None)?; - expr.to_tokens_with_context(s, context)?; + expr.to_tokens(s, context)?; s.append(TK_RP, None) } Self::ForeignKey { @@ -1662,9 +1671,9 @@ impl ToTokens for TableConstraint { comma(columns, s, context)?; s.append(TK_RP, None)?; s.append(TK_REFERENCES, None)?; - clause.to_tokens_with_context(s, context)?; + clause.to_tokens(s, context)?; if let Some(deref_clause) = deref_clause { - deref_clause.to_tokens_with_context(s, context)?; + deref_clause.to_tokens(s, context)?; } Ok(()) } @@ -1672,8 +1681,9 @@ impl ToTokens for TableConstraint { } } +impl_display_for_to_tokens!(SortOrder); impl ToTokens for SortOrder { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, _: &C, @@ -1688,8 +1698,9 @@ impl ToTokens for SortOrder { } } +impl_display_for_to_tokens!(NullsOrder); impl ToTokens for NullsOrder { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, _: &C, @@ -1705,27 +1716,29 @@ impl ToTokens for NullsOrder { } } +impl_display_for_to_tokens!(ForeignKeyClause); impl ToTokens for ForeignKeyClause { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { - self.tbl_name.to_tokens_with_context(s, context)?; + self.tbl_name.to_tokens(s, context)?; if !self.columns.is_empty() { s.append(TK_LP, None)?; comma(&self.columns, s, context)?; s.append(TK_RP, None)?; } for arg in &self.args { - arg.to_tokens_with_context(s, context)?; + arg.to_tokens(s, context)?; } Ok(()) } } +impl_display_for_to_tokens!(RefArg); impl ToTokens for RefArg { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -1734,28 +1747,29 @@ impl ToTokens for RefArg { Self::OnDelete(ref action) => { s.append(TK_ON, None)?; s.append(TK_DELETE, None)?; - action.to_tokens_with_context(s, context) + action.to_tokens(s, context) } Self::OnInsert(ref action) => { s.append(TK_ON, None)?; s.append(TK_INSERT, None)?; - action.to_tokens_with_context(s, context) + action.to_tokens(s, context) } Self::OnUpdate(ref action) => { s.append(TK_ON, None)?; s.append(TK_UPDATE, None)?; - action.to_tokens_with_context(s, context) + action.to_tokens(s, context) } Self::Match(ref name) => { s.append(TK_MATCH, None)?; - name.to_tokens_with_context(s, context) + name.to_tokens(s, context) } } } } +impl_display_for_to_tokens!(RefAct); impl ToTokens for RefAct { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, _: &C, @@ -1779,8 +1793,9 @@ impl ToTokens for RefAct { } } +impl_display_for_to_tokens!(DeferSubclause); impl ToTokens for DeferSubclause { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -1790,14 +1805,15 @@ impl ToTokens for DeferSubclause { } s.append(TK_DEFERRABLE, None)?; if let Some(init_deferred) = self.init_deferred { - init_deferred.to_tokens_with_context(s, context)?; + init_deferred.to_tokens(s, context)?; } Ok(()) } } +impl_display_for_to_tokens!(InitDeferredPred); impl ToTokens for InitDeferredPred { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, _: &C, @@ -1813,26 +1829,28 @@ impl ToTokens for InitDeferredPred { } } +impl_display_for_to_tokens!(IndexedColumn); impl ToTokens for IndexedColumn { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { - self.col_name.to_tokens_with_context(s, context)?; + self.col_name.to_tokens(s, context)?; if let Some(ref collation_name) = self.collation_name { s.append(TK_COLLATE, None)?; - collation_name.to_tokens_with_context(s, context)?; + collation_name.to_tokens(s, context)?; } if let Some(order) = self.order { - order.to_tokens_with_context(s, context)?; + order.to_tokens(s, context)?; } Ok(()) } } +impl_display_for_to_tokens!(Indexed); impl ToTokens for Indexed { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -1841,7 +1859,7 @@ impl ToTokens for Indexed { Self::IndexedBy(ref name) => { s.append(TK_INDEXED, None)?; s.append(TK_BY, None)?; - name.to_tokens_with_context(s, context) + name.to_tokens(s, context) } Self::NotIndexed => { s.append(TK_NOT, None)?; @@ -1851,50 +1869,53 @@ impl ToTokens for Indexed { } } +impl_display_for_to_tokens!(SortedColumn); impl ToTokens for SortedColumn { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { - self.expr.to_tokens_with_context(s, context)?; + self.expr.to_tokens(s, context)?; if let Some(ref order) = self.order { - order.to_tokens_with_context(s, context)?; + order.to_tokens(s, context)?; } if let Some(ref nulls) = self.nulls { - nulls.to_tokens_with_context(s, context)?; + nulls.to_tokens(s, context)?; } Ok(()) } } +impl_display_for_to_tokens!(Limit); impl ToTokens for Limit { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { s.append(TK_LIMIT, None)?; - self.expr.to_tokens_with_context(s, context)?; + self.expr.to_tokens(s, context)?; if let Some(ref offset) = self.offset { s.append(TK_OFFSET, None)?; - offset.to_tokens_with_context(s, context)?; + offset.to_tokens(s, context)?; } Ok(()) } } +impl_display_for_to_tokens!(InsertBody); impl ToTokens for InsertBody { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { match self { Self::Select(select, upsert) => { - select.to_tokens_with_context(s, context)?; + select.to_tokens(s, context)?; if let Some(upsert) = upsert { - upsert.to_tokens_with_context(s, context)?; + upsert.to_tokens(s, context)?; } Ok(()) } @@ -1906,8 +1927,9 @@ impl ToTokens for InsertBody { } } +impl_display_for_to_tokens!(Set); impl ToTokens for Set { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -1920,12 +1942,13 @@ impl ToTokens for Set { s.append(TK_RP, None)?; } s.append(TK_EQ, None)?; - self.expr.to_tokens_with_context(s, context) + self.expr.to_tokens(s, context) } } +impl_display_for_to_tokens!(PragmaBody); impl ToTokens for PragmaBody { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -1933,19 +1956,20 @@ impl ToTokens for PragmaBody { match self { Self::Equals(value) => { s.append(TK_EQ, None)?; - value.to_tokens_with_context(s, context) + value.to_tokens(s, context) } Self::Call(value) => { s.append(TK_LP, None)?; - value.to_tokens_with_context(s, context)?; + value.to_tokens(s, context)?; s.append(TK_RP, None) } } } } +impl_display_for_to_tokens!(TriggerTime); impl ToTokens for TriggerTime { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, _: &C, @@ -1961,8 +1985,9 @@ impl ToTokens for TriggerTime { } } +impl_display_for_to_tokens!(TriggerEvent); impl ToTokens for TriggerEvent { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -1980,8 +2005,9 @@ impl ToTokens for TriggerEvent { } } +impl_display_for_to_tokens!(TriggerCmd); impl ToTokens for TriggerCmd { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -1997,18 +2023,18 @@ impl ToTokens for TriggerCmd { s.append(TK_UPDATE, None)?; if let Some(or_conflict) = or_conflict { s.append(TK_OR, None)?; - or_conflict.to_tokens_with_context(s, context)?; + or_conflict.to_tokens(s, context)?; } - tbl_name.to_tokens_with_context(s, context)?; + tbl_name.to_tokens(s, context)?; s.append(TK_SET, None)?; comma(sets, s, context)?; if let Some(from) = from { s.append(TK_FROM, None)?; - from.to_tokens_with_context(s, context)?; + from.to_tokens(s, context)?; } if let Some(where_clause) = where_clause { s.append(TK_WHERE, None)?; - where_clause.to_tokens_with_context(s, context)?; + where_clause.to_tokens(s, context)?; } Ok(()) } @@ -2026,19 +2052,19 @@ impl ToTokens for TriggerCmd { s.append(TK_INSERT, None)?; if let Some(or_conflict) = or_conflict { s.append(TK_OR, None)?; - or_conflict.to_tokens_with_context(s, context)?; + or_conflict.to_tokens(s, context)?; } } s.append(TK_INTO, None)?; - tbl_name.to_tokens_with_context(s, context)?; + tbl_name.to_tokens(s, context)?; if !col_names.is_empty() { s.append(TK_LP, None)?; comma(col_names, s, context)?; s.append(TK_RP, None)?; } - select.to_tokens_with_context(s, context)?; + select.to_tokens(s, context)?; if let Some(upsert) = upsert { - upsert.to_tokens_with_context(s, context)?; + upsert.to_tokens(s, context)?; } if !returning.is_empty() { s.append(TK_RETURNING, None)?; @@ -2052,20 +2078,21 @@ impl ToTokens for TriggerCmd { } => { s.append(TK_DELETE, None)?; s.append(TK_FROM, None)?; - tbl_name.to_tokens_with_context(s, context)?; + tbl_name.to_tokens(s, context)?; if let Some(where_clause) = where_clause { s.append(TK_WHERE, None)?; - where_clause.to_tokens_with_context(s, context)?; + where_clause.to_tokens(s, context)?; } Ok(()) } - Self::Select(select) => select.to_tokens_with_context(s, context), + Self::Select(select) => select.to_tokens(s, context), } } } +impl_display_for_to_tokens!(ResolveType); impl ToTokens for ResolveType { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, _: &C, @@ -2083,8 +2110,9 @@ impl ToTokens for ResolveType { } } +impl_display_for_to_tokens!(With); impl ToTokens for With { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -2097,13 +2125,14 @@ impl ToTokens for With { } } +impl_display_for_to_tokens!(CommonTableExpr); impl ToTokens for CommonTableExpr { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { - self.tbl_name.to_tokens_with_context(s, context)?; + self.tbl_name.to_tokens(s, context)?; if !self.columns.is_empty() { s.append(TK_LP, None)?; comma(&self.columns, s, context)?; @@ -2121,13 +2150,14 @@ impl ToTokens for CommonTableExpr { } }; s.append(TK_LP, None)?; - self.select.to_tokens_with_context(s, context)?; + self.select.to_tokens(s, context)?; s.append(TK_RP, None) } } +impl_display_for_to_tokens!(Type); impl ToTokens for Type { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -2137,32 +2167,34 @@ impl ToTokens for Type { Some(ref size) => { s.append(TK_ID, Some(&self.name))?; // TODO check there is no forbidden chars s.append(TK_LP, None)?; - size.to_tokens_with_context(s, context)?; + size.to_tokens(s, context)?; s.append(TK_RP, None) } } } } +impl_display_for_to_tokens!(TypeSize); impl ToTokens for TypeSize { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { match self { - Self::MaxSize(size) => size.to_tokens_with_context(s, context), + Self::MaxSize(size) => size.to_tokens(s, context), Self::TypeSize(size1, size2) => { - size1.to_tokens_with_context(s, context)?; + size1.to_tokens(s, context)?; s.append(TK_COMMA, None)?; - size2.to_tokens_with_context(s, context) + size2.to_tokens(s, context) } } } } +impl_display_for_to_tokens!(TransactionType); impl ToTokens for TransactionType { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, _: &C, @@ -2178,8 +2210,9 @@ impl ToTokens for TransactionType { } } +impl_display_for_to_tokens!(Upsert); impl ToTokens for Upsert { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -2187,18 +2220,19 @@ impl ToTokens for Upsert { s.append(TK_ON, None)?; s.append(TK_CONFLICT, None)?; if let Some(ref index) = self.index { - index.to_tokens_with_context(s, context)?; + index.to_tokens(s, context)?; } - self.do_clause.to_tokens_with_context(s, context)?; + self.do_clause.to_tokens(s, context)?; if let Some(ref next) = self.next { - next.to_tokens_with_context(s, context)?; + next.to_tokens(s, context)?; } Ok(()) } } +impl_display_for_to_tokens!(UpsertIndex); impl ToTokens for UpsertIndex { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -2208,14 +2242,15 @@ impl ToTokens for UpsertIndex { s.append(TK_RP, None)?; if let Some(ref where_clause) = self.where_clause { s.append(TK_WHERE, None)?; - where_clause.to_tokens_with_context(s, context)?; + where_clause.to_tokens(s, context)?; } Ok(()) } } +impl_display_for_to_tokens!(UpsertDo); impl ToTokens for UpsertDo { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -2228,7 +2263,7 @@ impl ToTokens for UpsertDo { comma(sets, s, context)?; if let Some(where_clause) = where_clause { s.append(TK_WHERE, None)?; - where_clause.to_tokens_with_context(s, context)?; + where_clause.to_tokens(s, context)?; } Ok(()) } @@ -2240,8 +2275,9 @@ impl ToTokens for UpsertDo { } } +impl_display_for_to_tokens!(FunctionTail); impl ToTokens for FunctionTail { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -2250,51 +2286,54 @@ impl ToTokens for FunctionTail { s.append(TK_FILTER, None)?; s.append(TK_LP, None)?; s.append(TK_WHERE, None)?; - filter_clause.to_tokens_with_context(s, context)?; + filter_clause.to_tokens(s, context)?; s.append(TK_RP, None)?; } if let Some(ref over_clause) = self.over_clause { s.append(TK_OVER, None)?; - over_clause.to_tokens_with_context(s, context)?; + over_clause.to_tokens(s, context)?; } Ok(()) } } +impl_display_for_to_tokens!(Over); impl ToTokens for Over { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { match self { - Self::Window(ref window) => window.to_tokens_with_context(s, context), - Self::Name(ref name) => name.to_tokens_with_context(s, context), + Self::Window(ref window) => window.to_tokens(s, context), + Self::Name(ref name) => name.to_tokens(s, context), } } } +impl_display_for_to_tokens!(WindowDef); impl ToTokens for WindowDef { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { - self.name.to_tokens_with_context(s, context)?; + self.name.to_tokens(s, context)?; s.append(TK_AS, None)?; - self.window.to_tokens_with_context(s, context) + self.window.to_tokens(s, context) } } +impl_display_for_to_tokens!(Window); impl ToTokens for Window { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { s.append(TK_LP, None)?; if let Some(ref base) = self.base { - base.to_tokens_with_context(s, context)?; + base.to_tokens(s, context)?; } if !self.partition_by.is_empty() { s.append(TK_PARTITION, None)?; @@ -2307,37 +2346,39 @@ impl ToTokens for Window { comma(&self.order_by, s, context)?; } if let Some(ref frame_clause) = self.frame_clause { - frame_clause.to_tokens_with_context(s, context)?; + frame_clause.to_tokens(s, context)?; } s.append(TK_RP, None) } } +impl_display_for_to_tokens!(FrameClause); impl ToTokens for FrameClause { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, ) -> Result<(), S::Error> { - self.mode.to_tokens_with_context(s, context)?; + self.mode.to_tokens(s, context)?; if let Some(ref end) = self.end { s.append(TK_BETWEEN, None)?; - self.start.to_tokens_with_context(s, context)?; + self.start.to_tokens(s, context)?; s.append(TK_AND, None)?; - end.to_tokens_with_context(s, context)?; + end.to_tokens(s, context)?; } else { - self.start.to_tokens_with_context(s, context)?; + self.start.to_tokens(s, context)?; } if let Some(ref exclude) = self.exclude { s.append(TK_EXCLUDE, None)?; - exclude.to_tokens_with_context(s, context)?; + exclude.to_tokens(s, context)?; } Ok(()) } } +impl_display_for_to_tokens!(FrameMode); impl ToTokens for FrameMode { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, _: &C, @@ -2353,8 +2394,9 @@ impl ToTokens for FrameMode { } } +impl_display_for_to_tokens!(FrameBound); impl ToTokens for FrameBound { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, context: &C, @@ -2365,11 +2407,11 @@ impl ToTokens for FrameBound { s.append(TK_ROW, None) } Self::Following(value) => { - value.to_tokens_with_context(s, context)?; + value.to_tokens(s, context)?; s.append(TK_FOLLOWING, None) } Self::Preceding(value) => { - value.to_tokens_with_context(s, context)?; + value.to_tokens(s, context)?; s.append(TK_PRECEDING, None) } Self::UnboundedFollowing => { @@ -2384,8 +2426,9 @@ impl ToTokens for FrameBound { } } +impl_display_for_to_tokens!(FrameExclude); impl ToTokens for FrameExclude { - fn to_tokens_with_context( + fn to_tokens( &self, s: &mut S, _: &C, diff --git a/parser/src/parser.rs b/parser/src/parser.rs index 652562359..cfb10f28e 100644 --- a/parser/src/parser.rs +++ b/parser/src/parser.rs @@ -11483,14 +11483,23 @@ mod tests { ]; for (input, expected) in test_cases { - println!("Testing input: {:?}", from_bytes(input)); + let input_str = from_bytes(input); let parser = Parser::new(input); let mut results = Vec::new(); for cmd in parser { results.push(cmd.unwrap()); } - assert_eq!(results, expected, "Input: {input:?}"); + assert_eq!(results, expected, "Input: {input_str:?}"); + + // to_string tests + for (i, r) in results.iter().enumerate() { + let rstring = r.to_string(); + // put new string into parser again + let result = Parser::new(rstring.as_bytes()).next().unwrap().unwrap(); + let expected = &expected[i]; + assert_eq!(result, expected.clone(), "Input: {rstring:?}"); + } } } } diff --git a/simulator/model/mod.rs b/simulator/model/mod.rs index 73863f725..690426346 100644 --- a/simulator/model/mod.rs +++ b/simulator/model/mod.rs @@ -5,14 +5,14 @@ use itertools::Itertools; use serde::{Deserialize, Serialize}; use sql_generation::model::{ query::{ - Create, CreateIndex, Delete, Drop, EmptyContext, Insert, Select, + Create, CreateIndex, Delete, Drop, Insert, Select, select::{CompoundOperator, FromClause, ResultColumn, SelectInner}, transaction::{Begin, Commit, Rollback}, update::Update, }, table::{JoinTable, JoinType, SimValue, Table, TableContext}, }; -use turso_parser::ast::{Distinctness, fmt::ToTokens}; +use turso_parser::ast::Distinctness; use crate::{generation::Shadow, runner::env::SimulatorTables}; @@ -307,7 +307,7 @@ impl Shadow for SelectInner { } else { return Err(anyhow::anyhow!( "Failed to evaluate expression in free select ({})", - expr.0.format_with_context(&EmptyContext {}).unwrap() + expr.0 )); } } diff --git a/sql_generation/model/query/mod.rs b/sql_generation/model/query/mod.rs index 5bf0cecde..11d117a53 100644 --- a/sql_generation/model/query/mod.rs +++ b/sql_generation/model/query/mod.rs @@ -4,7 +4,6 @@ pub use delete::Delete; pub use drop::Drop; pub use insert::Insert; pub use select::Select; -use turso_parser::ast::fmt::ToSqlContext; pub mod create; pub mod create_index; @@ -15,20 +14,3 @@ pub mod predicate; pub mod select; pub mod transaction; pub mod update; - -/// Used to print sql strings that already have all the context it needs -pub struct EmptyContext; - -impl ToSqlContext for EmptyContext { - fn get_column_name( - &self, - _table_id: turso_parser::ast::TableInternalId, - _col_idx: usize, - ) -> String { - unreachable!() - } - - fn get_table_name(&self, _id: turso_parser::ast::TableInternalId) -> &str { - unreachable!() - } -} diff --git a/sql_generation/model/query/predicate.rs b/sql_generation/model/query/predicate.rs index 29f0b966c..50a72fee4 100644 --- a/sql_generation/model/query/predicate.rs +++ b/sql_generation/model/query/predicate.rs @@ -1,7 +1,10 @@ use std::fmt::Display; use serde::{Deserialize, Serialize}; -use turso_parser::ast::{self, fmt::ToTokens}; +use turso_parser::ast::{ + self, + fmt::{BlankContext, ToTokens}, +}; use crate::model::table::{SimValue, Table, TableContext}; @@ -142,6 +145,6 @@ pub fn expr_to_value( impl Display for Predicate { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.0.to_fmt(f) + self.0.displayer(&BlankContext).fmt(f) } } diff --git a/sql_generation/model/query/select.rs b/sql_generation/model/query/select.rs index 6c34888ff..ea4a375db 100644 --- a/sql_generation/model/query/select.rs +++ b/sql_generation/model/query/select.rs @@ -3,13 +3,14 @@ use std::{collections::HashSet, fmt::Display}; pub use ast::Distinctness; use itertools::Itertools; use serde::{Deserialize, Serialize}; -use turso_parser::ast::{self, fmt::ToTokens, SortOrder}; - -use crate::model::{ - query::EmptyContext, - table::{JoinTable, JoinType, JoinedTable, Table}, +use turso_parser::ast::{ + self, + fmt::{BlankContext, ToTokens}, + SortOrder, }; +use crate::model::table::{JoinTable, JoinType, JoinedTable, Table}; + use super::predicate::Predicate; /// `SELECT` or `RETURNING` result column @@ -366,7 +367,7 @@ impl Select { impl Display for Select { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.to_sql_ast().to_fmt_with_context(f, &EmptyContext {}) + self.to_sql_ast().displayer(&BlankContext).fmt(f) } }