diff --git a/.clippy.toml b/.clippy.toml new file mode 100644 index 000000000..3795dd22f --- /dev/null +++ b/.clippy.toml @@ -0,0 +1,9 @@ +doc-valid-idents = [ + "SeaQL", + "SeaQuery", + "MySQL", + "SQLite", + "MariaDB", + "PostgreSQL", + "..", +] diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 5b8ac56d0..1cb5eb128 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -55,7 +55,7 @@ jobs: with: toolchain: stable components: clippy - - run: cargo clippy --features=all-features --workspace -- -D warnings + - run: cargo clippy --features=all-features --workspace -- -D warnings -A clippy::semicolon_if_nothing_returned - run: cargo clippy --manifest-path sea-query-sqlx/Cargo.toml --workspace --features runtime-async-std-rustls --features=with-chrono,with-json,with-rust_decimal,with-bigdecimal,with-uuid,with-time,with-ipnetwork,with-mac_address,postgres-array,postgres-vector -- -D warnings - run: cargo clippy --manifest-path sea-query-rusqlite/Cargo.toml --all-features --workspace -- -D warnings - run: cargo clippy --manifest-path sea-query-postgres/Cargo.toml --all-features --workspace -- -D warnings diff --git a/src/audit/common.rs b/src/audit/common.rs index e3d8ad0e9..52e8acef6 100644 --- a/src/audit/common.rs +++ b/src/audit/common.rs @@ -3,9 +3,9 @@ use crate::TableRef; pub(super) fn parse_audit_table(table_ref: &TableRef) -> Option { match table_ref { - TableRef::SubQuery(_, _) => None, - TableRef::FunctionCall(_, _) => None, TableRef::Table(tbl, _) => Some(tbl.clone()), - TableRef::ValuesList(_, _) => None, + TableRef::ValuesList(_, _) | TableRef::FunctionCall(_, _) | TableRef::SubQuery(_, _) => { + None + } } } diff --git a/src/audit/insert.rs b/src/audit/insert.rs index cb3fc342c..0893f1582 100644 --- a/src/audit/insert.rs +++ b/src/audit/insert.rs @@ -22,7 +22,7 @@ impl AuditTrait for InsertStatement { }); if let Some(InsertValueSource::Select(select)) = &self.source { - requests.append(&mut select.audit()?.requests) + requests.append(&mut select.audit()?.requests); } if let Some(with) = &self.with { diff --git a/src/audit/mod.rs b/src/audit/mod.rs index 44e427789..ed72a28c1 100644 --- a/src/audit/mod.rs +++ b/src/audit/mod.rs @@ -71,25 +71,25 @@ impl QueryAccessAudit { .collect() } - /// Warning: this discards the schema part of SchemaTable. + /// Warning: this discards the schema part of [`SchemaTable`]. /// Intended for testing only. pub fn selected_tables(&self) -> Vec { self.filter_table_with_access_type(AccessType::Select) } - /// Warning: this discards the schema part of SchemaTable. + /// Warning: this discards the schema part of [`SchemaTable`]. /// Intended for testing only. pub fn inserted_tables(&self) -> Vec { self.filter_table_with_access_type(AccessType::Insert) } - /// Warning: this discards the schema part of SchemaTable. + /// Warning: this discards the schema part of [`SchemaTable`]. /// Intended for testing only. pub fn updated_tables(&self) -> Vec { self.filter_table_with_access_type(AccessType::Update) } - /// Warning: this discards the schema part of SchemaTable. + /// Warning: this discards the schema part of [`SchemaTable`]. /// Intended for testing only. pub fn deleted_tables(&self) -> Vec { self.filter_table_with_access_type(AccessType::Delete) diff --git a/src/audit/select.rs b/src/audit/select.rs index 681d7a3ea..649069f29 100644 --- a/src/audit/select.rs +++ b/src/audit/select.rs @@ -109,7 +109,6 @@ impl Walker { fn recurse_audit_expr(&mut self, expr: &Expr) -> Result<(), Error> { match expr { - Expr::Column(_) => (), Expr::Unary(_, expr) | Expr::AsEnum(_, expr) => self.recurse_audit_expr(expr)?, Expr::FunctionCall(function) => self.recurse_audit_function(function)?, Expr::Binary(left, _, right) => { @@ -117,18 +116,19 @@ impl Walker { self.recurse_audit_expr(right)?; } Expr::SubQuery(_, subquery) => self.recurse_audit_subquery(subquery)?, - Expr::Value(_) => (), - Expr::Values(_) => (), - Expr::Custom(_) => (), Expr::CustomWithExpr(_, exprs) | Expr::Tuple(exprs) => { for expr in exprs { self.recurse_audit_expr(expr)?; } } - Expr::Keyword(_) => (), Expr::Case(case) => self.recurse_audit_case(case)?, - Expr::Constant(_) => (), - Expr::TypeName(_) => (), + Expr::Value(_) + | Expr::Column(_) + | Expr::Values(_) + | Expr::Custom(_) + | Expr::Keyword(_) + | Expr::Constant(_) + | Expr::TypeName(_) => (), } Ok(()) } @@ -213,13 +213,14 @@ impl Walker { ConditionHolderContents::Chain(chain) => { for oper in chain { match oper { - LogicalChainOper::And(expr) => self.recurse_audit_expr(expr)?, - LogicalChainOper::Or(expr) => self.recurse_audit_expr(expr)?, + LogicalChainOper::Or(expr) | LogicalChainOper::And(expr) => { + self.recurse_audit_expr(expr)?; + } } } } ConditionHolderContents::Condition(condition) => { - self.recurse_audit_condition(condition)? + self.recurse_audit_condition(condition)?; } } Ok(()) @@ -262,7 +263,7 @@ fn wrap_result(access: Vec) -> QueryAccessAudit { AccessType::Insert => &mut insert_set, AccessType::Update => &mut update_set, AccessType::Delete => &mut delete_set, - _ => todo!(), + AccessType::Schema(_) => todo!(), }; if set.contains(&access.schema_table) { None diff --git a/src/backend/foreign_key_builder.rs b/src/backend/foreign_key_builder.rs index ae7bc9883..64f463fe3 100644 --- a/src/backend/foreign_key_builder.rs +++ b/src/backend/foreign_key_builder.rs @@ -15,7 +15,7 @@ pub trait ForeignKeyBuilder: QuotedBuilder + TableRefBuilder { create: &ForeignKeyCreateStatement, sql: &mut dyn SqlWriter, ) { - self.prepare_foreign_key_create_statement_internal(create, sql, Mode::Alter) + self.prepare_foreign_key_create_statement_internal(create, sql, Mode::Alter); } /// Translate [`ForeignKeyDropStatement`] into SQL statement. @@ -24,7 +24,7 @@ pub trait ForeignKeyBuilder: QuotedBuilder + TableRefBuilder { drop: &ForeignKeyDropStatement, sql: &mut dyn SqlWriter, ) { - self.prepare_foreign_key_drop_statement_internal(drop, sql, Mode::Alter) + self.prepare_foreign_key_drop_statement_internal(drop, sql, Mode::Alter); } /// Translate [`ForeignKeyAction`] into SQL statement. @@ -44,7 +44,7 @@ pub trait ForeignKeyBuilder: QuotedBuilder + TableRefBuilder { ForeignKeyAction::SetDefault => "SET DEFAULT", } ) - .unwrap() + .unwrap(); } /// Translate [`TableRef`] into SQL statement. diff --git a/src/backend/mod.rs b/src/backend/mod.rs index af4210751..5a97467e4 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -51,9 +51,9 @@ pub trait QuotedBuilder { Cow::Owned(s) => { for char in s.chars() { if char == qq { - sql.write_char(char).unwrap() + sql.write_char(char).unwrap(); } - sql.write_char(char).unwrap() + sql.write_char(char).unwrap(); } } }; @@ -93,7 +93,7 @@ pub trait EscapeBuilder { '\r' => buffer.write_str("\\r"), _ => buffer.write_char(c), } - .unwrap() + .unwrap(); } } @@ -164,45 +164,31 @@ impl Oper { pub(crate) fn is_logical(&self) -> bool { matches!( self, - Oper::UnOper(UnOper::Not) | Oper::BinOper(BinOper::And) | Oper::BinOper(BinOper::Or) + Oper::UnOper(UnOper::Not) | Oper::BinOper(BinOper::And | BinOper::Or) ) } pub(crate) fn is_between(&self) -> bool { - matches!( - self, - Oper::BinOper(BinOper::Between) | Oper::BinOper(BinOper::NotBetween) - ) + matches!(self, Oper::BinOper(BinOper::Between | BinOper::NotBetween)) } pub(crate) fn is_like(&self) -> bool { - matches!( - self, - Oper::BinOper(BinOper::Like) | Oper::BinOper(BinOper::NotLike) - ) + matches!(self, Oper::BinOper(BinOper::Like | BinOper::NotLike)) } pub(crate) fn is_in(&self) -> bool { - matches!( - self, - Oper::BinOper(BinOper::In) | Oper::BinOper(BinOper::NotIn) - ) + matches!(self, Oper::BinOper(BinOper::In | BinOper::NotIn)) } pub(crate) fn is_is(&self) -> bool { - matches!( - self, - Oper::BinOper(BinOper::Is) | Oper::BinOper(BinOper::IsNot) - ) + matches!(self, Oper::BinOper(BinOper::Is | BinOper::IsNot)) } pub(crate) fn is_shift(&self) -> bool { - matches!( - self, - Oper::BinOper(BinOper::LShift) | Oper::BinOper(BinOper::RShift) - ) + matches!(self, Oper::BinOper(BinOper::LShift | BinOper::RShift)) } + #[allow(clippy::match_wildcard_for_single_variants)] pub(crate) fn is_arithmetic(&self) -> bool { match self { Oper::BinOper(b) => { @@ -215,6 +201,7 @@ impl Oper { } } + #[allow(clippy::match_wildcard_for_single_variants)] pub(crate) fn is_comparison(&self) -> bool { match self { Oper::BinOper(b) => { diff --git a/src/backend/mysql/foreign_key.rs b/src/backend/mysql/foreign_key.rs index a3edf1f05..26e309f14 100644 --- a/src/backend/mysql/foreign_key.rs +++ b/src/backend/mysql/foreign_key.rs @@ -5,7 +5,7 @@ impl ForeignKeyBuilder for MysqlQueryBuilder { match table_ref { // Support only "naked" table names with no schema or alias. TableRef::Table(TableName(None, _), None) => { - self.prepare_table_ref_iden(table_ref, sql) + self.prepare_table_ref_iden(table_ref, sql); } _ => panic!("Not supported"), } diff --git a/src/backend/mysql/index.rs b/src/backend/mysql/index.rs index e96344d71..6deb1e875 100644 --- a/src/backend/mysql/index.rs +++ b/src/backend/mysql/index.rs @@ -62,7 +62,7 @@ impl IndexBuilder for MysqlQueryBuilder { match table_ref { // Support only "naked" table names with no schema or alias. TableRef::Table(TableName(None, _), None) => { - self.prepare_table_ref_iden(table_ref, sql) + self.prepare_table_ref_iden(table_ref, sql); } _ => panic!("Not supported"), } diff --git a/src/backend/mysql/query.rs b/src/backend/mysql/query.rs index cbe6d753d..d114f2dac 100644 --- a/src/backend/mysql/query.rs +++ b/src/backend/mysql/query.rs @@ -2,7 +2,7 @@ use super::*; use crate::extension::mysql::*; impl QueryBuilder for MysqlQueryBuilder { - fn values_list_tuple_prefix(&self) -> &str { + fn values_list_tuple_prefix(&self) -> &'static str { "ROW" } @@ -21,24 +21,24 @@ impl QueryBuilder for MysqlQueryBuilder { } for (i, hint) in select.index_hints.iter().enumerate() { if i != 0 { - write!(sql, " ").unwrap() + write!(sql, " ").unwrap(); } match hint.r#type { IndexHintType::Use => { write!(sql, "USE INDEX ",).unwrap(); - self.prepare_index_hint_scope(&hint.scope, sql); + Self::prepare_index_hint_scope(hint.scope, sql); write!(sql, "(").unwrap(); self.prepare_iden(&hint.index, sql); } IndexHintType::Ignore => { write!(sql, "IGNORE INDEX ",).unwrap(); - self.prepare_index_hint_scope(&hint.scope, sql); + Self::prepare_index_hint_scope(hint.scope, sql); write!(sql, "(").unwrap(); self.prepare_iden(&hint.index, sql); } IndexHintType::Force => { write!(sql, "FORCE INDEX ",).unwrap(); - self.prepare_index_hint_scope(&hint.scope, sql); + Self::prepare_index_hint_scope(hint.scope, sql); write!(sql, "(").unwrap(); self.prepare_iden(&hint.index, sql); } @@ -90,19 +90,15 @@ impl QueryBuilder for MysqlQueryBuilder { column: &DynIden, sql: &mut dyn SqlWriter, ) { - use std::ops::Deref; - if !from.is_empty() { - if let Some(table) = table { + if let Some(TableRef::Table(TableName(None, table), None)) = table.as_deref() { // Support only "naked" table names with no schema or alias. - if let TableRef::Table(TableName(None, table), None) = table.deref() { - let column_name = ColumnName::from((table.clone(), column.clone())); - self.prepare_column_ref(&ColumnRef::Column(column_name), sql); - return; - } + let column_name = ColumnName::from((table.clone(), column.clone())); + self.prepare_column_ref(&ColumnRef::Column(column_name), sql); + return; } } - self.prepare_iden(column, sql) + self.prepare_iden(column, sql); } fn prepare_update_condition( @@ -129,11 +125,11 @@ impl QueryBuilder for MysqlQueryBuilder { None => (), Some(NullOrdering::Last) => { self.prepare_simple_expr(&order_expr.expr, sql); - write!(sql, " IS NULL ASC, ").unwrap() + write!(sql, " IS NULL ASC, ").unwrap(); } Some(NullOrdering::First) => { self.prepare_simple_expr(&order_expr.expr, sql); - write!(sql, " IS NULL DESC, ").unwrap() + write!(sql, " IS NULL DESC, ").unwrap(); } } if !matches!(order_expr.order, Order::Field(_)) { @@ -157,19 +153,19 @@ impl QueryBuilder for MysqlQueryBuilder { ) { match on_conflict_action { Some(OnConflictAction::DoNothing(pk_cols)) => { - if !pk_cols.is_empty() { + if pk_cols.is_empty() { + write!(sql, " IGNORE").unwrap(); + } else { self.prepare_on_conflict_do_update_keywords(sql); pk_cols.iter().fold(true, |first, pk_col| { if !first { - write!(sql, ", ").unwrap() + write!(sql, ", ").unwrap(); } self.prepare_iden(pk_col, sql); write!(sql, " = ").unwrap(); self.prepare_iden(pk_col, sql); false }); - } else { - write!(sql, " IGNORE").unwrap(); } } _ => self.prepare_on_conflict_action_common(on_conflict_action, sql), @@ -194,17 +190,17 @@ impl QueryBuilder for MysqlQueryBuilder { fn prepare_returning(&self, _returning: &Option, _sql: &mut dyn SqlWriter) {} - fn random_function(&self) -> &str { + fn random_function(&self) -> &'static str { "RAND" } - fn insert_default_keyword(&self) -> &str { + fn insert_default_keyword(&self) -> &'static str { "()" } } impl MysqlQueryBuilder { - fn prepare_index_hint_scope(&self, index_hint_scope: &IndexHintScope, sql: &mut dyn SqlWriter) { + fn prepare_index_hint_scope(index_hint_scope: IndexHintScope, sql: &mut dyn SqlWriter) { match index_hint_scope { IndexHintScope::Join => { write!(sql, "FOR JOIN ").unwrap(); diff --git a/src/backend/mysql/table.rs b/src/backend/mysql/table.rs index 9ca0c1a7e..cb1a09740 100644 --- a/src/backend/mysql/table.rs +++ b/src/backend/mysql/table.rs @@ -7,7 +7,7 @@ impl TableBuilder for MysqlQueryBuilder { let comment = self.escape_string(comment); write!(sql, " COMMENT '{comment}'").unwrap(); } - self.prepare_table_opt_def(create, sql) + self.prepare_table_opt_def(create, sql); } fn prepare_column_def(&self, column_def: &ColumnDef, sql: &mut dyn SqlWriter) { @@ -18,7 +18,7 @@ impl TableBuilder for MysqlQueryBuilder { self.prepare_column_type(column_type, sql); } - for column_spec in column_def.spec.iter() { + for column_spec in &column_def.spec { write!(sql, " ").unwrap(); self.prepare_column_spec(column_spec, sql); } @@ -42,13 +42,12 @@ impl TableBuilder for MysqlQueryBuilder { ColumnType::BigInteger | ColumnType::BigUnsigned => write!(sql, "bigint"), ColumnType::Float => write!(sql, "float"), ColumnType::Double => write!(sql, "double"), - ColumnType::Decimal(precision) => match precision { + ColumnType::Decimal(precision) | ColumnType::Money(precision) => match precision { Some((precision, scale)) => write!(sql, "decimal({precision}, {scale})"), None => write!(sql, "decimal"), }, ColumnType::DateTime => write!(sql, "datetime"), - ColumnType::Timestamp => write!(sql, "timestamp"), - ColumnType::TimestampWithTimeZone => write!(sql, "timestamp"), + ColumnType::Timestamp | ColumnType::TimestampWithTimeZone => write!(sql, "timestamp"), ColumnType::Time => write!(sql, "time"), ColumnType::Date => write!(sql, "date"), ColumnType::Year => write!(sql, "year"), @@ -66,12 +65,7 @@ impl TableBuilder for MysqlQueryBuilder { }, ColumnType::VarBit(length) => write!(sql, "bit({length})"), ColumnType::Boolean => write!(sql, "bool"), - ColumnType::Money(precision) => match precision { - Some((precision, scale)) => write!(sql, "decimal({precision}, {scale})"), - None => write!(sql, "decimal"), - }, - ColumnType::Json => write!(sql, "json"), - ColumnType::JsonBinary => write!(sql, "json"), + ColumnType::Json | ColumnType::JsonBinary => write!(sql, "json"), ColumnType::Uuid => write!(sql, "binary(16)"), ColumnType::Custom(iden) => write!(sql, "{iden}"), ColumnType::Enum { variants, .. } => { @@ -107,7 +101,7 @@ impl TableBuilder for MysqlQueryBuilder { } } - fn column_spec_auto_increment_keyword(&self) -> &str { + fn column_spec_auto_increment_keyword(&self) -> &'static str { "AUTO_INCREMENT" } @@ -191,6 +185,6 @@ impl TableBuilder for MysqlQueryBuilder { /// column comment fn column_comment(&self, comment: &str, sql: &mut dyn SqlWriter) { let comment = self.escape_string(comment); - write!(sql, "COMMENT '{comment}'").unwrap() + write!(sql, "COMMENT '{comment}'").unwrap(); } } diff --git a/src/backend/postgres/extension.rs b/src/backend/postgres/extension.rs index 68f28b6d2..29f79c4e7 100644 --- a/src/backend/postgres/extension.rs +++ b/src/backend/postgres/extension.rs @@ -10,7 +10,7 @@ impl ExtensionBuilder for PostgresQueryBuilder { write!(sql, "CREATE EXTENSION ").unwrap(); if create.if_not_exists { - write!(sql, "IF NOT EXISTS ").unwrap() + write!(sql, "IF NOT EXISTS ").unwrap(); } write!(sql, "{}", create.name).unwrap(); diff --git a/src/backend/postgres/query.rs b/src/backend/postgres/query.rs index 8ff2eddd7..fd3455a8b 100644 --- a/src/backend/postgres/query.rs +++ b/src/backend/postgres/query.rs @@ -192,7 +192,7 @@ impl QueryBuilder for PostgresQueryBuilder { write!(buffer, "'").unwrap(); } - fn if_null_function(&self) -> &str { + fn if_null_function(&self) -> &'static str { "COALESCE" } } @@ -200,18 +200,20 @@ impl QueryBuilder for PostgresQueryBuilder { fn is_pg_comparison(b: &BinOper) -> bool { matches!( b, - BinOper::PgOperator(PgBinOper::Contained) - | BinOper::PgOperator(PgBinOper::Contains) - | BinOper::PgOperator(PgBinOper::Similarity) - | BinOper::PgOperator(PgBinOper::WordSimilarity) - | BinOper::PgOperator(PgBinOper::StrictWordSimilarity) - | BinOper::PgOperator(PgBinOper::Matches) + BinOper::PgOperator( + PgBinOper::Contained + | PgBinOper::Contains + | PgBinOper::Similarity + | PgBinOper::WordSimilarity + | PgBinOper::StrictWordSimilarity + | PgBinOper::Matches + ) ) } fn is_ilike(b: &BinOper) -> bool { matches!( b, - BinOper::PgOperator(PgBinOper::ILike) | BinOper::PgOperator(PgBinOper::NotILike) + BinOper::PgOperator(PgBinOper::ILike | PgBinOper::NotILike) ) } diff --git a/src/backend/postgres/table.rs b/src/backend/postgres/table.rs index f8d3feb5a..413a354d6 100644 --- a/src/backend/postgres/table.rs +++ b/src/backend/postgres/table.rs @@ -22,8 +22,10 @@ impl TableBuilder for PostgresQueryBuilder { _ => "varchar".into(), }, ColumnType::Text => "text".into(), - ColumnType::TinyInteger | ColumnType::TinyUnsigned => "smallint".into(), - ColumnType::SmallInteger | ColumnType::SmallUnsigned => "smallint".into(), + ColumnType::TinyInteger + | ColumnType::TinyUnsigned + | ColumnType::SmallInteger + | ColumnType::SmallUnsigned => "smallint".into(), ColumnType::Integer | ColumnType::Unsigned => "integer".into(), ColumnType::BigInteger | ColumnType::BigUnsigned => "bigint".into(), ColumnType::Float => "real".into(), @@ -84,13 +86,14 @@ impl TableBuilder for PostgresQueryBuilder { ColumnType::LTree => "ltree".into(), } ) - .unwrap() + .unwrap(); } - fn column_spec_auto_increment_keyword(&self) -> &str { + fn column_spec_auto_increment_keyword(&self) -> &'static str { "" } + #[expect(clippy::too_many_lines, reason = "TODO")] fn prepare_table_alter_statement(&self, alter: &TableAlterStatement, sql: &mut dyn SqlWriter) { if alter.options.is_empty() { panic!("No alter option found") @@ -122,7 +125,7 @@ impl TableBuilder for PostgresQueryBuilder { .iter() .any(|v| matches!(v, ColumnSpec::AutoIncrement)) { - self.prepare_column_auto_increment(column_type, sql); + Self::prepare_column_auto_increment(column_type, sql); } else { self.prepare_column_type(column_type, sql); } @@ -151,7 +154,6 @@ impl TableBuilder for PostgresQueryBuilder { write!(sql, ", ").unwrap(); } match column_spec { - ColumnSpec::AutoIncrement => {} ColumnSpec::Null => { write!(sql, "ALTER COLUMN ").unwrap(); self.prepare_iden(&column_def.name, sql); @@ -160,7 +162,7 @@ impl TableBuilder for PostgresQueryBuilder { ColumnSpec::NotNull => { write!(sql, "ALTER COLUMN ").unwrap(); self.prepare_iden(&column_def.name, sql); - write!(sql, " SET NOT NULL").unwrap() + write!(sql, " SET NOT NULL").unwrap(); } ColumnSpec::Default(v) => { write!(sql, "ALTER COLUMN ").unwrap(); @@ -179,13 +181,14 @@ impl TableBuilder for PostgresQueryBuilder { write!(sql, ")").unwrap(); } ColumnSpec::Check(check) => self.prepare_check_constraint(check, sql), - ColumnSpec::Generated { .. } => {} ColumnSpec::Extra(string) => write!(sql, "{string}").unwrap(), - ColumnSpec::Comment(_) => {} ColumnSpec::Using(expr) => { write!(sql, " USING ").unwrap(); QueryBuilder::prepare_simple_expr(self, expr, sql); } + ColumnSpec::Generated { .. } + | ColumnSpec::AutoIncrement + | ColumnSpec::Comment(_) => {} } false }); @@ -241,7 +244,7 @@ impl TableBuilder for PostgresQueryBuilder { } impl PostgresQueryBuilder { - fn prepare_column_auto_increment(&self, column_type: &ColumnType, sql: &mut dyn SqlWriter) { + fn prepare_column_auto_increment(column_type: &ColumnType, sql: &mut dyn SqlWriter) { let num_ty = match column_type { ColumnType::SmallInteger => "smallint", ColumnType::Integer => "integer", @@ -266,7 +269,7 @@ impl PostgresQueryBuilder { write!(sql, " ").unwrap(); if is_auto_increment.is_some() { - self.prepare_column_auto_increment(column_type, sql); + Self::prepare_column_auto_increment(column_type, sql); } else { self.prepare_column_type(column_type, sql); } @@ -281,7 +284,7 @@ impl PostgresQueryBuilder { f(column_def, sql); - for column_spec in column_def.spec.iter() { + for column_spec in &column_def.spec { if matches!(column_spec, ColumnSpec::AutoIncrement) { continue; } diff --git a/src/backend/postgres/types.rs b/src/backend/postgres/types.rs index 198fe5cfa..9e6bc4ff1 100644 --- a/src/backend/postgres/types.rs +++ b/src/backend/postgres/types.rs @@ -11,7 +11,7 @@ impl TypeBuilder for PostgresQueryBuilder { if let Some(as_type) = &create.as_type { write!(sql, " AS ").unwrap(); - self.prepare_create_as_type(as_type, sql); + Self::prepare_create_as_type(as_type, sql); } if !create.values.is_empty() { @@ -45,7 +45,7 @@ impl TypeBuilder for PostgresQueryBuilder { if let Some(option) = &drop.option { write!(sql, " ").unwrap(); - self.prepare_drop_type_opt(option, sql); + Self::prepare_drop_type_opt(option, sql); } } @@ -57,13 +57,13 @@ impl TypeBuilder for PostgresQueryBuilder { } if let Some(option) = &alter.option { - self.prepare_alter_type_opt(option, sql) + self.prepare_alter_type_opt(option, sql); } } } impl PostgresQueryBuilder { - fn prepare_create_as_type(&self, as_type: &TypeAs, sql: &mut dyn SqlWriter) { + fn prepare_create_as_type(as_type: &TypeAs, sql: &mut dyn SqlWriter) { write!( sql, "{}", @@ -71,10 +71,10 @@ impl PostgresQueryBuilder { TypeAs::Enum => "ENUM", } ) - .unwrap() + .unwrap(); } - fn prepare_drop_type_opt(&self, opt: &TypeDropOpt, sql: &mut dyn SqlWriter) { + fn prepare_drop_type_opt(opt: &TypeDropOpt, sql: &mut dyn SqlWriter) { write!( sql, "{}", @@ -83,7 +83,7 @@ impl PostgresQueryBuilder { TypeDropOpt::Restrict => "RESTRICT", } ) - .unwrap() + .unwrap(); } fn prepare_alter_type_opt(&self, opt: &TypeAlterOpt, sql: &mut dyn SqlWriter) { diff --git a/src/backend/query_builder.rs b/src/backend/query_builder.rs index 496e29c37..0087c0016 100644 --- a/src/backend/query_builder.rs +++ b/src/backend/query_builder.rs @@ -1,4 +1,4 @@ -use std::{fmt, ops::Deref}; +use std::fmt; use crate::*; @@ -13,6 +13,7 @@ pub trait QueryBuilder: } /// Prefix for tuples in VALUES list (e.g. ROW for MySQL) + #[expect(clippy::unnecessary_literal_bound, reason = "compatibility")] fn values_list_tuple_prefix(&self) -> &str { "" } @@ -43,7 +44,7 @@ pub trait QueryBuilder: write!(sql, "(").unwrap(); insert.columns.iter().fold(true, |first, col| { if !first { - write!(sql, ", ").unwrap() + write!(sql, ", ").unwrap(); } self.prepare_iden(col, sql); false @@ -59,12 +60,12 @@ pub trait QueryBuilder: write!(sql, "VALUES ").unwrap(); values.iter().fold(true, |first, row| { if !first { - write!(sql, ", ").unwrap() + write!(sql, ", ").unwrap(); } write!(sql, "(").unwrap(); row.iter().fold(true, |first, col| { if !first { - write!(sql, ", ").unwrap() + write!(sql, ", ").unwrap(); } self.prepare_simple_expr(col, sql); false @@ -74,7 +75,7 @@ pub trait QueryBuilder: }); } InsertValueSource::Select(select_query) => { - self.prepare_select_statement(select_query.deref(), sql); + self.prepare_select_statement(select_query, sql); } } } @@ -116,7 +117,7 @@ pub trait QueryBuilder: select.selects.iter().fold(true, |first, expr| { if !first { - write!(sql, ", ").unwrap() + write!(sql, ", ").unwrap(); } self.prepare_select_expr(expr, sql); false @@ -126,7 +127,7 @@ pub trait QueryBuilder: write!(sql, " FROM ").unwrap(); select.from.iter().fold(true, |first, table_ref| { if !first { - write!(sql, ", ").unwrap() + write!(sql, ", ").unwrap(); } self.prepare_table_ref(table_ref, sql); false @@ -136,7 +137,7 @@ pub trait QueryBuilder: } if !select.join.is_empty() { - for expr in select.join.iter() { + for expr in &select.join { write!(sql, " ").unwrap(); self.prepare_join_expr(expr, sql); } @@ -148,7 +149,7 @@ pub trait QueryBuilder: write!(sql, " GROUP BY ").unwrap(); select.groups.iter().fold(true, |first, expr| { if !first { - write!(sql, ", ").unwrap() + write!(sql, ", ").unwrap(); } self.prepare_simple_expr(expr, sql); false @@ -167,7 +168,7 @@ pub trait QueryBuilder: write!(sql, " ORDER BY ").unwrap(); select.orders.iter().fold(true, |first, expr| { if !first { - write!(sql, ", ").unwrap() + write!(sql, ", ").unwrap(); } self.prepare_order_expr(expr, sql); false @@ -221,7 +222,7 @@ pub trait QueryBuilder: update.values.iter().fold(true, |first, row| { if !first { - write!(sql, ", ").unwrap() + write!(sql, ", ").unwrap(); } let (col, v) = row; self.prepare_update_column(&update.table, &update.from, col, sql); @@ -256,7 +257,7 @@ pub trait QueryBuilder: from.iter().fold(true, |first, table_ref| { if !first { - write!(sql, ", ").unwrap() + write!(sql, ", ").unwrap(); } self.prepare_table_ref(table_ref, sql); @@ -384,10 +385,10 @@ pub trait QueryBuilder: } Expr::Binary(left, op, right) => match (op, right.as_ref()) { (BinOper::In, Expr::Tuple(t)) if t.is_empty() => { - self.binary_expr(&1i32.into(), &BinOper::Equal, &2i32.into(), sql) + self.binary_expr(&1i32.into(), &BinOper::Equal, &2i32.into(), sql); } (BinOper::NotIn, Expr::Tuple(t)) if t.is_empty() => { - self.binary_expr(&1i32.into(), &BinOper::Equal, &1i32.into(), sql) + self.binary_expr(&1i32.into(), &BinOper::Equal, &1i32.into(), sql); } _ => self.binary_expr(left, op, right, sql), }, @@ -396,7 +397,7 @@ pub trait QueryBuilder: self.prepare_sub_query_oper(oper, sql); } write!(sql, "(").unwrap(); - self.prepare_query_statement(sel.deref(), sql); + self.prepare_query_statement(sel, sql); write!(sql, ")").unwrap(); } Expr::Value(val) => { @@ -466,7 +467,7 @@ pub trait QueryBuilder: let CaseStatement { when, r#else } = stmts; - for case in when.iter() { + for case in when { write!(sql, " WHEN (").unwrap(); self.prepare_condition_where(&case.condition, sql); write!(sql, ") THEN ").unwrap(); @@ -719,7 +720,7 @@ pub trait QueryBuilder: /// Translate [`Function`] into SQL statement. fn prepare_function_name_common(&self, function: &Func, sql: &mut dyn SqlWriter) { if let Func::Custom(iden) = function { - write!(sql, "{iden}").unwrap() + write!(sql, "{iden}").unwrap(); } else { write!( sql, @@ -772,7 +773,7 @@ pub trait QueryBuilder: fn prepare_with_query(&self, query: &WithQuery, sql: &mut dyn SqlWriter) { self.prepare_with_clause(&query.with_clause, sql); - self.prepare_query_statement(query.query.as_ref().unwrap().deref(), sql); + self.prepare_query_statement(query.query.as_ref().unwrap(), sql); } fn prepare_with_clause(&self, with_clause: &WithClause, sql: &mut dyn SqlWriter) { @@ -870,7 +871,7 @@ pub trait QueryBuilder: write!(sql, "(").unwrap(); - self.prepare_query_statement(cte.query.as_ref().unwrap().deref(), sql); + self.prepare_query_statement(cte.query.as_ref().unwrap(), sql); write!(sql, ") ").unwrap(); } @@ -886,7 +887,7 @@ pub trait QueryBuilder: "{} MATERIALIZED ", if materialized { "" } else { "NOT" } ) - .unwrap() + .unwrap(); } } @@ -907,12 +908,12 @@ pub trait QueryBuilder: } fn prepare_function_name(&self, function: &Func, sql: &mut dyn SqlWriter) { - self.prepare_function_name_common(function, sql) + self.prepare_function_name_common(function, sql); } /// Translate [`JoinType`] into SQL statement. fn prepare_join_type(&self, join_type: &JoinType, sql: &mut dyn SqlWriter) { - self.prepare_join_type_common(join_type, sql) + self.prepare_join_type_common(join_type, sql); } fn prepare_join_type_common(&self, join_type: &JoinType, sql: &mut dyn SqlWriter) { @@ -928,7 +929,7 @@ pub trait QueryBuilder: JoinType::FullOuterJoin => "FULL OUTER JOIN", } ) - .unwrap() + .unwrap(); } /// Translate [`OrderExpr`] into SQL statement. @@ -1041,6 +1042,7 @@ pub trait QueryBuilder: } #[doc(hidden)] + #[expect(clippy::too_many_lines, reason = "TODO")] fn write_value(&self, buf: &mut dyn Write, value: &Value) -> fmt::Result { match value { Value::Bool(None) @@ -1116,7 +1118,7 @@ pub trait QueryBuilder: Value::Double(Some(v)) => write!(buf, "{v}")?, Value::String(Some(v)) => self.write_string_quoted(v, buf), Value::Char(Some(v)) => { - self.write_string_quoted(std::str::from_utf8(&[*v as u8]).unwrap(), buf) + self.write_string_quoted(std::str::from_utf8(&[*v as u8]).unwrap(), buf); } Value::Bytes(Some(v)) => self.write_bytes(v, buf), #[cfg(feature = "with-json")] @@ -1127,31 +1129,31 @@ pub trait QueryBuilder: Value::ChronoTime(Some(v)) => write!(buf, "'{}'", v.format("%H:%M:%S%.6f")).unwrap(), #[cfg(feature = "with-chrono")] Value::ChronoDateTime(Some(v)) => { - write!(buf, "'{}'", v.format("%Y-%m-%d %H:%M:%S%.6f")).unwrap() + write!(buf, "'{}'", v.format("%Y-%m-%d %H:%M:%S%.6f")).unwrap(); } #[cfg(feature = "with-chrono")] Value::ChronoDateTimeUtc(Some(v)) => { - write!(buf, "'{}'", v.format("%Y-%m-%d %H:%M:%S%.6f %:z")).unwrap() + write!(buf, "'{}'", v.format("%Y-%m-%d %H:%M:%S%.6f %:z")).unwrap(); } #[cfg(feature = "with-chrono")] Value::ChronoDateTimeLocal(Some(v)) => { - write!(buf, "'{}'", v.format("%Y-%m-%d %H:%M:%S%.6f %:z")).unwrap() + write!(buf, "'{}'", v.format("%Y-%m-%d %H:%M:%S%.6f %:z")).unwrap(); } #[cfg(feature = "with-chrono")] Value::ChronoDateTimeWithTimeZone(Some(v)) => { - write!(buf, "'{}'", v.format("%Y-%m-%d %H:%M:%S%.6f %:z")).unwrap() + write!(buf, "'{}'", v.format("%Y-%m-%d %H:%M:%S%.6f %:z")).unwrap(); } #[cfg(feature = "with-time")] Value::TimeDate(Some(v)) => { - write!(buf, "'{}'", v.format(time_format::FORMAT_DATE).unwrap())? + write!(buf, "'{}'", v.format(time_format::FORMAT_DATE).unwrap())?; } #[cfg(feature = "with-time")] Value::TimeTime(Some(v)) => { - write!(buf, "'{}'", v.format(time_format::FORMAT_TIME).unwrap())? + write!(buf, "'{}'", v.format(time_format::FORMAT_TIME).unwrap())?; } #[cfg(feature = "with-time")] Value::TimeDateTime(Some(v)) => { - write!(buf, "'{}'", v.format(time_format::FORMAT_DATETIME).unwrap())? + write!(buf, "'{}'", v.format(time_format::FORMAT_DATETIME).unwrap())?; } #[cfg(feature = "with-time")] Value::TimeDateTimeWithTimeZone(Some(v)) => write!( @@ -1169,19 +1171,19 @@ pub trait QueryBuilder: #[cfg(feature = "with-jiff")] Value::JiffDateTime(Some(v)) => { use crate::with_jiff::JIFF_DATE_TIME_FMT_STR; - write!(buf, "'{}'", v.strftime(JIFF_DATE_TIME_FMT_STR))? + write!(buf, "'{}'", v.strftime(JIFF_DATE_TIME_FMT_STR))?; } #[cfg(feature = "with-jiff")] Value::JiffTimestamp(Some(v)) => { use crate::with_jiff::JIFF_TIMESTAMP_FMT_STR; - write!(buf, "'{}'", v.strftime(JIFF_TIMESTAMP_FMT_STR))? + write!(buf, "'{}'", v.strftime(JIFF_TIMESTAMP_FMT_STR))?; } #[cfg(feature = "with-jiff")] Value::JiffZoned(Some(v)) => { // Zoned map to timestamp with timezone use crate::with_jiff::JIFF_ZONE_FMT_STR; - write!(buf, "'{}'", v.strftime(JIFF_ZONE_FMT_STR))? + write!(buf, "'{}'", v.strftime(JIFF_ZONE_FMT_STR))?; } #[cfg(feature = "with-rust_decimal")] Value::Decimal(Some(v)) => write!(buf, "{v}")?, @@ -1260,7 +1262,7 @@ pub trait QueryBuilder: write!(sql, "(").unwrap(); on_conflict_targets.iter().fold(true, |first, target| { if !first { - write!(sql, ", ").unwrap() + write!(sql, ", ").unwrap(); } match target { OnConflictTarget::ConflictColumn(col) => { @@ -1300,7 +1302,7 @@ pub trait QueryBuilder: self.prepare_on_conflict_do_update_keywords(sql); update_strats.iter().fold(true, |first, update_strat| { if !first { - write!(sql, ", ").unwrap() + write!(sql, ", ").unwrap(); } match update_strat { OnConflictUpdate::Column(col) => { @@ -1354,7 +1356,7 @@ pub trait QueryBuilder: on_conflict_condition: &ConditionHolder, sql: &mut dyn SqlWriter, ) { - self.prepare_condition(on_conflict_condition, "WHERE", sql) + self.prepare_condition(on_conflict_condition, "WHERE", sql); } #[doc(hidden)] @@ -1371,7 +1373,7 @@ pub trait QueryBuilder: ReturningClause::Columns(cols) => { cols.iter().fold(true, |first, column_ref| { if !first { - write!(sql, ", ").unwrap() + write!(sql, ", ").unwrap(); } self.prepare_column_ref(column_ref, sql); false @@ -1380,7 +1382,7 @@ pub trait QueryBuilder: ReturningClause::Exprs(exprs) => { exprs.iter().fold(true, |first, expr| { if !first { - write!(sql, ", ").unwrap() + write!(sql, ", ").unwrap(); } self.prepare_simple_expr(expr, sql); false @@ -1445,7 +1447,7 @@ pub trait QueryBuilder: write!(sql, "PARTITION BY ").unwrap(); window.partition_by.iter().fold(true, |first, expr| { if !first { - write!(sql, ", ").unwrap() + write!(sql, ", ").unwrap(); } self.prepare_simple_expr(expr, sql); false @@ -1456,7 +1458,7 @@ pub trait QueryBuilder: write!(sql, " ORDER BY ").unwrap(); window.order_by.iter().fold(true, |first, expr| { if !first { - write!(sql, ", ").unwrap() + write!(sql, ", ").unwrap(); } self.prepare_order_expr(expr, sql); false @@ -1538,7 +1540,7 @@ pub trait QueryBuilder: #[doc(hidden)] /// Write a string surrounded by escaped quotes. fn write_string_quoted(&self, string: &str, buffer: &mut dyn Write) { - write!(buffer, "'{}'", self.escape_string(string)).unwrap() + write!(buffer, "'{}'", self.escape_string(string)).unwrap(); } #[doc(hidden)] @@ -1553,37 +1555,37 @@ pub trait QueryBuilder: #[doc(hidden)] /// The name of the function that represents the "if null" condition. - fn if_null_function(&self) -> &str { + fn if_null_function(&self) -> &'static str { "IFNULL" } #[doc(hidden)] /// The name of the function that represents the "greatest" function. - fn greatest_function(&self) -> &str { + fn greatest_function(&self) -> &'static str { "GREATEST" } #[doc(hidden)] /// The name of the function that represents the "least" function. - fn least_function(&self) -> &str { + fn least_function(&self) -> &'static str { "LEAST" } #[doc(hidden)] /// The name of the function that returns the char length. - fn char_length_function(&self) -> &str { + fn char_length_function(&self) -> &'static str { "CHAR_LENGTH" } #[doc(hidden)] /// The name of the function that returns a random number - fn random_function(&self) -> &str { + fn random_function(&self) -> &'static str { // Returning it with parens as part of the name because the tuple preparer can't deal with empty lists "RANDOM" } /// The keywords for insert default row. - fn insert_default_keyword(&self) -> &str { + fn insert_default_keyword(&self) -> &'static str { "(DEFAULT)" } @@ -1592,7 +1594,7 @@ pub trait QueryBuilder: write!(sql, "VALUES ").unwrap(); (0..num_rows).fold(true, |first, _| { if !first { - write!(sql, ", ").unwrap() + write!(sql, ", ").unwrap(); } write!(sql, "{}", self.insert_default_keyword()).unwrap(); false diff --git a/src/backend/sqlite/foreign_key.rs b/src/backend/sqlite/foreign_key.rs index 9c4368a7d..1168a5204 100644 --- a/src/backend/sqlite/foreign_key.rs +++ b/src/backend/sqlite/foreign_key.rs @@ -5,7 +5,7 @@ impl ForeignKeyBuilder for SqliteQueryBuilder { match table_ref { // Support only "naked" table names with no schema or alias. TableRef::Table(TableName(None, _), None) => { - self.prepare_table_ref_iden(table_ref, sql) + self.prepare_table_ref_iden(table_ref, sql); } _ => panic!("Not supported"), } diff --git a/src/backend/sqlite/index.rs b/src/backend/sqlite/index.rs index 7adbb803b..e7177e6b4 100644 --- a/src/backend/sqlite/index.rs +++ b/src/backend/sqlite/index.rs @@ -39,7 +39,7 @@ impl IndexBuilder for SqliteQueryBuilder { match table_ref { // Support only "naked" table names with no schema or alias. TableRef::Table(TableName(None, _), None) => { - self.prepare_table_ref_iden(table_ref, sql) + self.prepare_table_ref_iden(table_ref, sql); } _ => panic!("Not supported"), } diff --git a/src/backend/sqlite/query.rs b/src/backend/sqlite/query.rs index 02fdd556b..460bb5422 100644 --- a/src/backend/sqlite/query.rs +++ b/src/backend/sqlite/query.rs @@ -76,20 +76,20 @@ impl QueryBuilder for SqliteQueryBuilder { sql.push_param(value, self as _); } - fn greatest_function(&self) -> &str { + fn greatest_function(&self) -> &'static str { "MAX" } - fn least_function(&self) -> &str { + fn least_function(&self) -> &'static str { "MIN" } - fn char_length_function(&self) -> &str { + fn char_length_function(&self) -> &'static str { "LENGTH" } fn insert_default_values(&self, _: u32, sql: &mut dyn SqlWriter) { // SQLite doesn't support inserting multiple rows with default values - write!(sql, "DEFAULT VALUES").unwrap() + write!(sql, "DEFAULT VALUES").unwrap(); } } diff --git a/src/backend/sqlite/table.rs b/src/backend/sqlite/table.rs index c821e9bf8..070689784 100644 --- a/src/backend/sqlite/table.rs +++ b/src/backend/sqlite/table.rs @@ -6,13 +6,13 @@ impl TableBuilder for SqliteQueryBuilder { if let Some(column_type) = &column_def.types { write!(sql, " ").unwrap(); - self.prepare_column_type(&column_def.spec, column_type, sql); + Self::prepare_column_type(&column_def.spec, column_type, sql); } let mut is_primary_key = false; let mut is_auto_increment = false; - for column_spec in column_def.spec.iter() { + for column_spec in &column_def.spec { if matches!(column_spec, ColumnSpec::PrimaryKey) { is_primary_key = true; continue; @@ -39,10 +39,10 @@ impl TableBuilder for SqliteQueryBuilder { } fn prepare_column_type(&self, column_type: &ColumnType, sql: &mut dyn SqlWriter) { - self.prepare_column_type(&[], column_type, sql) + Self::prepare_column_type(&[], column_type, sql); } - fn column_spec_auto_increment_keyword(&self) -> &str { + fn column_spec_auto_increment_keyword(&self) -> &'static str { "AUTOINCREMENT" } @@ -91,12 +91,7 @@ impl TableBuilder for SqliteQueryBuilder { write!(sql, "DROP COLUMN ").unwrap(); self.prepare_iden(col_name, sql); } - TableAlterOption::DropForeignKey(_) => { - panic!( - "Sqlite does not support modification of foreign key constraints to existing tables" - ); - } - TableAlterOption::AddForeignKey(_) => { + TableAlterOption::DropForeignKey(_) | TableAlterOption::AddForeignKey(_) => { panic!( "Sqlite does not support modification of foreign key constraints to existing tables" ); @@ -122,7 +117,6 @@ impl TableBuilder for SqliteQueryBuilder { impl SqliteQueryBuilder { fn prepare_column_type( - &self, column_specs: &[ColumnSpec], column_type: &ColumnType, sql: &mut dyn SqlWriter, @@ -198,7 +192,7 @@ impl SqliteQueryBuilder { ColumnType::LTree => unimplemented!("LTree is not available in Sqlite."), } ) - .unwrap() + .unwrap(); } } diff --git a/src/backend/table_builder.rs b/src/backend/table_builder.rs index c6fbf0880..26244c423 100644 --- a/src/backend/table_builder.rs +++ b/src/backend/table_builder.rs @@ -100,13 +100,13 @@ pub trait TableBuilder: QueryBuilder::prepare_simple_expr(self, value, sql); } ColumnSpec::AutoIncrement => { - write!(sql, "{}", self.column_spec_auto_increment_keyword()).unwrap() + write!(sql, "{}", self.column_spec_auto_increment_keyword()).unwrap(); } ColumnSpec::UniqueKey => write!(sql, "UNIQUE").unwrap(), ColumnSpec::PrimaryKey => write!(sql, "PRIMARY KEY").unwrap(), ColumnSpec::Check(check) => self.prepare_check_constraint(check, sql), ColumnSpec::Generated { expr, stored } => { - self.prepare_generated_column(expr, *stored, sql) + self.prepare_generated_column(expr, *stored, sql); } ColumnSpec::Extra(string) => write!(sql, "{string}").unwrap(), ColumnSpec::Comment(comment) => self.column_comment(comment, sql), @@ -122,12 +122,12 @@ pub trait TableBuilder: /// Translate [`TableOpt`] into SQL statement. fn prepare_table_opt(&self, create: &TableCreateStatement, sql: &mut dyn SqlWriter) { - self.prepare_table_opt_def(create, sql) + self.prepare_table_opt_def(create, sql); } /// Default function fn prepare_table_opt_def(&self, create: &TableCreateStatement, sql: &mut dyn SqlWriter) { - for table_opt in create.options.iter() { + for table_opt in &create.options { write!(sql, " ").unwrap(); write!( sql, @@ -138,7 +138,7 @@ pub trait TableBuilder: TableOpt::CharacterSet(s) => format!("DEFAULT CHARSET={s}"), } ) - .unwrap() + .unwrap(); } } @@ -162,7 +162,7 @@ pub trait TableBuilder: false }); - for drop_opt in drop.options.iter() { + for drop_opt in &drop.options { self.prepare_table_drop_opt(drop_opt, sql); } } diff --git a/src/expr.rs b/src/expr.rs index a5ac64174..08c09a017 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -713,7 +713,7 @@ pub trait ExprTrait: Sized { { self.binary( BinOper::In, - Expr::Tuple(v.into_iter().map(|v| v.into()).collect()), + Expr::Tuple(v.into_iter().map(Into::into).collect()), ) } @@ -816,7 +816,7 @@ pub trait ExprTrait: Sized { { self.binary( BinOper::NotIn, - Expr::Tuple(v.into_iter().map(|v| v.into()).collect()), + Expr::Tuple(v.into_iter().map(Into::into).collect()), ) } @@ -1510,7 +1510,7 @@ pub trait ExprTrait: Sized { } /// This generic implementation covers all expression types, -/// including [ColumnRef], [Value], [FunctionCall], [Expr]... +/// including [`ColumnRef`], [Value], [`FunctionCall`], [Expr]... impl ExprTrait for T where T: Into, diff --git a/src/extension/postgres/ltree.rs b/src/extension/postgres/ltree.rs index 848308449..5b115c8c5 100644 --- a/src/extension/postgres/ltree.rs +++ b/src/extension/postgres/ltree.rs @@ -5,7 +5,7 @@ use crate::Iden; /// `ltree` stores a raber path which in this struct is represented as the /// tuple's first value. /// -/// # PostcreSQL Reference +/// # PostgreSQL Reference /// /// The following set of SQL statements can be used to create a table with /// a `ltree` column. Here the `ltree` column is called `path`. @@ -51,7 +51,7 @@ use crate::Iden; pub struct PgLTree; impl Iden for PgLTree { - fn unquoted(&self) -> &str { + fn unquoted(&self) -> &'static str { "ltree" } } diff --git a/src/extension/postgres/types.rs b/src/extension/postgres/types.rs index e702c5621..b898fdc3b 100644 --- a/src/extension/postgres/types.rs +++ b/src/extension/postgres/types.rs @@ -198,7 +198,7 @@ impl TypeCreateStatement { T: IntoIden, I: IntoIterator, { - for v in values.into_iter() { + for v in values { self.values.push(v.into_iden()); } self @@ -275,7 +275,7 @@ impl TypeDropStatement { T: IntoTypeRef, I: IntoIterator, { - for n in names.into_iter() { + for n in names { self.names.push(n.into_type_ref()); } self diff --git a/src/foreign_key/common.rs b/src/foreign_key/common.rs index 597fd2b03..7968591b9 100644 --- a/src/foreign_key/common.rs +++ b/src/foreign_key/common.rs @@ -105,14 +105,11 @@ impl TableForeignKey { } pub fn get_columns(&self) -> Vec { - self.columns.iter().map(|col| col.to_string()).collect() + self.columns.iter().map(ToString::to_string).collect() } pub fn get_ref_columns(&self) -> Vec { - self.ref_columns - .iter() - .map(|ref_col| ref_col.to_string()) - .collect() + self.ref_columns.iter().map(ToString::to_string).collect() } pub fn get_on_delete(&self) -> Option { diff --git a/src/func.rs b/src/func.rs index 7c8b8977b..bc5a9b175 100644 --- a/src/func.rs +++ b/src/func.rs @@ -828,7 +828,7 @@ impl FunctionCall { where T: Into, { - self.arg_with(arg, Default::default()) + self.arg_with(arg, FuncArgMod::default()) } pub(crate) fn arg_with(mut self, arg: T, mod_: FuncArgMod) -> Self @@ -846,7 +846,7 @@ impl FunctionCall { I: IntoIterator, { self.args = args.into_iter().collect(); - self.mods = vec![Default::default(); self.args.len()]; + self.mods = vec![FuncArgMod::default(); self.args.len()]; self } diff --git a/src/index/common.rs b/src/index/common.rs index 4a76e3018..7b6d15471 100644 --- a/src/index/common.rs +++ b/src/index/common.rs @@ -166,7 +166,7 @@ impl TableIndex { pub fn get_column_names(&self) -> Vec { self.columns .iter() - .filter_map(|col| col.name().map(|name| name.to_string())) + .filter_map(|col| col.name().map(ToString::to_string)) .collect() } diff --git a/src/index/create.rs b/src/index/create.rs index c839f6fb6..7d30de59a 100644 --- a/src/index/create.rs +++ b/src/index/create.rs @@ -208,6 +208,7 @@ use super::common::*; /// ); /// ``` #[derive(Default, Debug, Clone)] +#[expect(clippy::struct_excessive_bools, reason = "Not a state machine")] pub struct IndexCreateStatement { pub(crate) table: Option, pub(crate) index: TableIndex, @@ -235,7 +236,7 @@ impl IndexCreateStatement { pub fn new() -> Self { Self { table: None, - index: Default::default(), + index: TableIndex::default(), primary: false, unique: false, nulls_not_distinct: false, @@ -299,7 +300,7 @@ impl IndexCreateStatement { /// Set index as full text. /// On MySQL, this is `FULLTEXT`. - /// On PgSQL, this is `GIN`. + /// On PostgreSQL, this is `GIN`. pub fn full_text(&mut self) -> &mut Self { self.index_type(IndexType::FullText) } diff --git a/src/lib.rs b/src/lib.rs index 71bb77ad2..3da248256 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,13 +1,24 @@ #![cfg_attr(docsrs, feature(doc_cfg))] -#![warn(clippy::nursery)] +#![warn(clippy::nursery, clippy::pedantic)] #![deny(missing_debug_implementations)] #![forbid(unsafe_code)] #![allow( + // compatibility clippy::derive_partial_eq_without_eq, - clippy::option_if_let_else, clippy::redundant_pub_crate, + clippy::missing_const_for_fn, + // We should consider enabling it someday. + // This would help users understand that the function returns a value instead of producing side effects. + clippy::must_use_candidate, + clippy::return_self_not_must_use, + // semantics + clippy::manual_assert, + // + clippy::option_if_let_else, clippy::use_self, - clippy::missing_const_for_fn + clippy::wildcard_imports, + clippy::enum_glob_use, + clippy::missing_errors_doc, )] //!
diff --git a/src/prepare.rs b/src/prepare.rs index 35f539f53..f89572ea3 100644 --- a/src/prepare.rs +++ b/src/prepare.rs @@ -69,7 +69,7 @@ impl SqlWriter for SqlWriterValues { } else { write!(self.string, "{}", self.placeholder).unwrap(); } - self.values.push(value) + self.values.push(value); } fn as_writer(&mut self) -> &mut dyn Write { diff --git a/src/query/condition.rs b/src/query/condition.rs index 2b76d12ac..eb0b23dfc 100644 --- a/src/query/condition.rs +++ b/src/query/condition.rs @@ -535,7 +535,7 @@ pub trait ConditionalStatement { /// ); /// ``` /// - /// Calling multiple times; will be ANDed togother + /// Calling this method multiple times will combine the conditions with AND. /// /// ``` /// use sea_query::{tests_cfg::*, *}; @@ -651,10 +651,13 @@ impl ConditionHolder { } } + /// # Panics + /// + /// Panics if you mixed `and_where`/`or_where` and `cond_where` in statements. pub fn add_and_or(&mut self, condition: LogicalChainOper) { match &mut self.contents { ConditionHolderContents::Empty => { - self.contents = ConditionHolderContents::Chain(vec![condition]) + self.contents = ConditionHolderContents::Chain(vec![condition]); } ConditionHolderContents::Chain(c) => c.push(condition), ConditionHolderContents::Condition(_) => { @@ -663,6 +666,9 @@ impl ConditionHolder { } } + /// # Panics + /// + /// Panics if you mixed `and_where`/`or_where` and `cond_where` in statements. pub fn add_condition(&mut self, mut addition: Condition) { match std::mem::take(&mut self.contents) { ConditionHolderContents::Empty => { diff --git a/src/query/delete.rs b/src/query/delete.rs index 8d8c9c560..6d5ecaacf 100644 --- a/src/query/delete.rs +++ b/src/query/delete.rs @@ -211,7 +211,7 @@ impl DeleteStatement { self.returning(ReturningClause::All) } - /// Create a [WithQuery] by specifying a [WithClause] to execute this query with. + /// Create a [`WithQuery`] by specifying a [`WithClause`] to execute this query with. /// /// # Examples /// @@ -260,7 +260,7 @@ impl DeleteStatement { clause.query(self) } - /// Create a Common Table Expression by specifying a [CommonTableExpression] or [WithClause] to execute this query with. + /// Create a Common Table Expression by specifying a [`CommonTableExpression`](crate::CommonTableExpression) or [`WithClause`] to execute this query with. /// /// # Examples /// diff --git a/src/query/insert.rs b/src/query/insert.rs index d095863b4..09fb00a1a 100644 --- a/src/query/insert.rs +++ b/src/query/insert.rs @@ -130,7 +130,7 @@ impl InsertStatement { C: IntoIden, I: IntoIterator, { - self.columns = columns.into_iter().map(|c| c.into_iden()).collect(); + self.columns = columns.into_iter().map(IntoIden::into_iden).collect(); self } @@ -197,13 +197,14 @@ impl InsertStatement { /// r#"INSERT INTO "glyph" ("image") SELECT 'hello' WHERE NOT EXISTS(SELECT 'world')"# /// ); /// ``` + /// ``` /// use sea_query::{audit::*, tests_cfg::*, *}; /// let query = Query::insert() /// .into_table(Glyph::Table) /// .columns([Glyph::Image]) /// .select_from( /// Query::select() - /// .expr(Font::Name) + /// .expr(Expr::col(Font::Name)) /// .from(Font::Table) /// .take(), /// ) @@ -294,7 +295,7 @@ impl InsertStatement { let values_source = if let Some(InsertValueSource::Values(values)) = &mut self.source { values } else { - self.source = Some(InsertValueSource::Values(Default::default())); + self.source = Some(InsertValueSource::Values(Vec::new())); if let Some(InsertValueSource::Values(values)) = &mut self.source { values } else { @@ -380,6 +381,10 @@ impl InsertStatement { /// assert_eq!(query.sql, new_query.sql); /// assert_eq!(query.values, new_query.values); /// ``` + /// + /// # Panics + /// + /// Panics if the length of columns and the lengh of values mismatch. pub fn values_panic(&mut self, values: I) -> &mut Self where I: IntoIterator, @@ -539,7 +544,7 @@ impl InsertStatement { self.returning(ReturningClause::All) } - /// Create a [WithQuery] by specifying a [WithClause] to execute this query with. + /// Create a [`WithQuery`] by specifying a [`WithClause`] to execute this query with. /// /// # Examples /// @@ -587,7 +592,7 @@ impl InsertStatement { clause.query(self) } - /// Create a Common Table Expression by specifying a [CommonTableExpression] or [WithClause] to execute this query with. + /// Create a Common Table Expression by specifying a [`CommonTableExpression`](crate::CommonTableExpression) or [`WithClause`] to execute this query with. /// /// # Examples /// diff --git a/src/query/on_conflict.rs b/src/query/on_conflict.rs index 05992426c..cc402b367 100644 --- a/src/query/on_conflict.rs +++ b/src/query/on_conflict.rs @@ -39,7 +39,7 @@ impl OnConflict { /// Create a ON CONFLICT expression without target column, /// a special method designed for MySQL pub fn new() -> Self { - Default::default() + Self::default() } /// Set ON CONFLICT target column diff --git a/src/query/returning.rs b/src/query/returning.rs index 8a412769c..7d670b711 100644 --- a/src/query/returning.rs +++ b/src/query/returning.rs @@ -106,7 +106,10 @@ impl Returning { T: IntoColumnRef, I: IntoIterator, { - let cols: Vec<_> = cols.into_iter().map(|c| c.into_column_ref()).collect(); + let cols: Vec<_> = cols + .into_iter() + .map(IntoColumnRef::into_column_ref) + .collect(); ReturningClause::Columns(cols) } diff --git a/src/query/select.rs b/src/query/select.rs index ddae04b62..173c98d97 100644 --- a/src/query/select.rs +++ b/src/query/select.rs @@ -75,7 +75,7 @@ pub enum SelectDistinct { #[derive(Debug, Clone, PartialEq)] #[non_exhaustive] pub enum WindowSelectType { - /// Name in [`SelectStatement`] + /// Name in [[`SelectStatement`]] Name(DynIden), /// Inline query in [`SelectExpr`] Query(WindowStatement), @@ -218,9 +218,9 @@ impl SelectStatement { F: FnOnce(&mut Self), { if b { - if_true(self) + if_true(self); } else { - if_false(self) + if_false(self); } self } @@ -369,7 +369,7 @@ impl SelectStatement { I: IntoIterator, { self.selects - .append(&mut exprs.into_iter().map(|c| c.into()).collect()); + .append(&mut exprs.into_iter().map(Into::into).collect()); self } @@ -448,12 +448,12 @@ impl SelectStatement { { let cols = cols .into_iter() - .map(|col| col.into_column_ref()) + .map(IntoColumnRef::into_column_ref) .collect::>(); - self.distinct = if !cols.is_empty() { - Some(SelectDistinct::DistinctOn(cols)) - } else { + self.distinct = if cols.is_empty() { None + } else { + Some(SelectDistinct::DistinctOn(cols)) }; self } @@ -921,6 +921,10 @@ impl SelectStatement { /// r#"SELECT * FROM (VALUES (1, 'hello'), (2, 'world')) AS "x""# /// ); /// ``` + /// + /// # Panics + /// + /// Panics if `value_tuples` is empty. pub fn from_values(&mut self, value_tuples: I, alias: A) -> &mut Self where I: IntoIterator, @@ -929,7 +933,7 @@ impl SelectStatement { { let value_tuples: Vec = value_tuples .into_iter() - .map(|vt| vt.into_value_tuple()) + .map(IntoValueTuple::into_value_tuple) .collect(); assert!(!value_tuples.is_empty()); self.from_from(TableRef::ValuesList(value_tuples, alias.into_iden())) @@ -2078,7 +2082,10 @@ impl SelectStatement { { self.lock = Some(LockClause { r#type, - tables: tables.into_iter().map(|t| t.into_table_ref()).collect(), + tables: tables + .into_iter() + .map(IntoTableRef::into_table_ref) + .collect(), behavior: None, }); self @@ -2159,7 +2166,10 @@ impl SelectStatement { { self.lock = Some(LockClause { r#type, - tables: tables.into_iter().map(|t| t.into_table_ref()).collect(), + tables: tables + .into_iter() + .map(IntoTableRef::into_table_ref) + .collect(), behavior: Some(behavior), }); self @@ -2227,7 +2237,7 @@ impl SelectStatement { self.lock(LockType::Update) } - /// Union with another SelectStatement that must have the same selected fields. + /// Union with another [`SelectStatement`] that must have the same selected fields. /// /// # Examples /// @@ -2268,7 +2278,7 @@ impl SelectStatement { self } - /// Union with multiple SelectStatement that must have the same selected fields. + /// Union with multiple [`SelectStatement`] that must have the same selected fields. /// /// # Examples /// @@ -2317,7 +2327,7 @@ impl SelectStatement { self } - /// Create a [WithQuery] by specifying a [WithClause] to execute this query with. + /// Create a [`WithQuery`] by specifying a [`WithClause`] to execute this query with. /// /// # Examples /// @@ -2387,7 +2397,7 @@ impl SelectStatement { clause.query(self) } - /// Create a Common Table Expression by specifying a [CommonTableExpression] or [WithClause] to execute this query with. + /// Create a Common Table Expression by specifying a [`CommonTableExpression`](crate::CommonTableExpression) or [`WithClause`] to execute this query with. /// /// # Examples /// diff --git a/src/query/traits.rs b/src/query/traits.rs index 3e854f09c..8eeb7f9ae 100644 --- a/src/query/traits.rs +++ b/src/query/traits.rs @@ -21,7 +21,7 @@ pub trait QueryStatementBuilder: Debug + Into { sql.to_string() } - /// Build corresponding SQL statement into the SqlWriter for certain database backend and collect query parameters + /// Build corresponding SQL statement into the [`SqlWriter`] for certain database backend and collect query parameters fn build_collect_any_into(&self, query_builder: &dyn QueryBuilder, sql: &mut dyn SqlWriter); fn into_sub_query_statement(self) -> SubQueryStatement { diff --git a/src/query/update.rs b/src/query/update.rs index b22011923..cca900560 100644 --- a/src/query/update.rs +++ b/src/query/update.rs @@ -176,7 +176,7 @@ impl UpdateStatement { T: IntoIden, I: IntoIterator, { - for (k, v) in values.into_iter() { + for (k, v) in values { self.values.push((k.into_iden(), Box::new(v))); } self @@ -350,7 +350,7 @@ impl UpdateStatement { self.returning(ReturningClause::All) } - /// Create a [WithQuery] by specifying a [WithClause] to execute this query with. + /// Create a [`WithQuery`] by specifying a [`WithClause`] to execute this query with. /// /// # Examples /// @@ -400,7 +400,7 @@ impl UpdateStatement { clause.query(self) } - /// Create a Common Table Expression by specifying a [CommonTableExpression] or [WithClause] to execute this query with. + /// Create a Common Table Expression by specifying a [`CommonTableExpression`](crate::CommonTableExpression) or [`WithClause`] to execute this query with. /// /// # Examples /// diff --git a/src/query/window.rs b/src/query/window.rs index c69078d21..4921837fc 100644 --- a/src/query/window.rs +++ b/src/query/window.rs @@ -39,7 +39,7 @@ pub trait OverStatement { } } -/// frame_start or frame_end clause +/// `frame_start` or `frame_end` clause #[derive(Debug, Clone, PartialEq)] pub enum Frame { UnboundedPreceding, @@ -103,6 +103,7 @@ impl WindowStatement { } /// Construct a new [`WindowStatement`] with PARTITION BY custom + #[expect(clippy::needless_pass_by_value, reason = "This needs more discussion")] pub fn partition_by_custom(col: T) -> Self where T: ToString, @@ -112,7 +113,7 @@ impl WindowStatement { window } - /// frame clause for frame_start + /// frame clause for `frame_start` /// # Examples: /// /// ``` @@ -145,7 +146,7 @@ impl WindowStatement { self.frame(r#type, start, None) } - /// frame clause for BETWEEN frame_start AND frame_end + /// frame clause for BETWEEN `frame_start` AND `frame_end` /// /// # Examples: /// diff --git a/src/query/with.rs b/src/query/with.rs index dcbc79356..8c8d4d374 100644 --- a/src/query/with.rs +++ b/src/query/with.rs @@ -5,26 +5,26 @@ use crate::{ }; use inherent::inherent; -/// A table definition inside a WITH clause ([WithClause]). +/// A table definition inside a WITH clause ([`WithClause`]). /// -/// A WITH clause can contain one or multiple common table expressions ([CommonTableExpression]). +/// A WITH clause can contain one or multiple common table expressions ([`CommonTableExpression`]). /// /// These named queries can act as a "query local table" that are materialized during execution and /// then can be used by the query prefixed with the WITH clause. /// -/// A WITH clause can contain multiple of these [CommonTableExpression]. (Except in the case of -/// recursive WITH query which can only contain one [CommonTableExpression]). +/// A WITH clause can contain multiple of these [`CommonTableExpression`]. (Except in the case of +/// recursive WITH query which can only contain one [`CommonTableExpression`]). /// -/// A [CommonTableExpression] is a name, column names and a query returning data for those columns. +/// A [`CommonTableExpression`] is a name, column names and a query returning data for those columns. /// /// Some databases (like sqlite) restrict the acceptable kinds of queries inside of the WITH clause -/// common table expressions. These databases only allow [SelectStatement]s to form a common table +/// common table expressions. These databases only allow [`SelectStatement`]s to form a common table /// expression. /// /// Other databases like postgres allow modification queries (UPDATE, DELETE) inside of the WITH /// clause but they have to return a table. (They must have a RETURNING clause). /// -/// sea-query doesn't check this or restrict the kind of [CommonTableExpression] that you can create +/// sea-query doesn't check this or restrict the kind of [`CommonTableExpression`] that you can create /// in rust. This means that you can put an UPDATE or DELETE queries into WITH clause and sea-query /// will succeed in generating that kind of sql query but the execution inside the database will /// fail because they are invalid. @@ -33,7 +33,7 @@ use inherent::inherent; /// sense and valid for that database that you are using. /// /// NOTE that for recursive WITH queries (in sql: "WITH RECURSIVE") you can only have a -/// single [CommonTableExpression] inside of the WITH clause. That query must match certain +/// single [`CommonTableExpression`] inside of the WITH clause. That query must match certain /// requirements: /// * It is a query of UNION or UNION ALL of two queries. /// * The first part of the query (the left side of the UNION) must be executable first in itself. @@ -41,11 +41,14 @@ use inherent::inherent; /// * The self reference must appear in the right hand side of the UNION. /// * The query can only have a single self-reference. /// * Recursive data-modifying statements are not supported, but you can use the results of a -/// recursive SELECT query in a data-modifying statement. (like so: WITH RECURSIVE -/// cte_name(a,b,c,d) AS (SELECT ... UNION SELECT ... FROM ... JOIN cte_name ON ... WHERE ...) -/// DELETE FROM table WHERE table.a = cte_name.a) -/// -/// It is mandatory to set the [Self::table_name] and the [Self::query]. +/// recursive SELECT query in a data-modifying statement. +/// like so: +/// ```sql +/// WITH RECURSIVE +/// cte_name(a,b,c,d) AS (SELECT ... UNION SELECT ... FROM ... JOIN cte_name ON ... WHERE ...) +/// DELETE FROM table WHERE table.a = cte_name.a +/// ``` +/// It is mandatory to set the [`Self::table_name`] the [`Self::query`]. #[derive(Debug, Clone, Default, PartialEq)] pub struct CommonTableExpression { pub(crate) table_name: Option, @@ -84,13 +87,12 @@ impl CommonTableExpression { T: IntoIden, I: IntoIterator, { - self.cols - .extend(cols.into_iter().map(|col| col.into_iden())); + self.cols.extend(cols.into_iter().map(IntoIden::into_iden)); self } /// Some databases allow you to put "MATERIALIZED" or "NOT MATERIALIZED" in the CTE definition. - /// This will affect how during the execution of [WithQuery] the CTE in the [WithClause] will be + /// This will affect how during the execution of [`WithQuery`] the CTE in the [`WithClause`] will be /// executed. If the database doesn't support this syntax this option specified here will be /// ignored and not appear in the generated sql. pub fn materialized(&mut self, materialized: bool) -> &mut Self { @@ -108,9 +110,9 @@ impl CommonTableExpression { self } - /// Create a CTE from a [SelectStatement] if the selections are named columns then this will - /// return a [CommonTableExpression] that has the column names set. The [Self::table_name] is - /// set if the [SelectStatement] from clause contains at least one table. + /// Create a CTE from a [`SelectStatement`] if the selections are named columns then this will + /// return a [`CommonTableExpression`] that has the column names set. The [`Self::table_name`] is + /// set if the [`SelectStatement`] from clause contains at least one table. pub fn from_select(select: SelectStatement) -> Self { let mut cte = Self::default(); cte.try_set_cols_from_selects(&select.selects); @@ -126,10 +128,10 @@ impl CommonTableExpression { } fn set_table_name_from_select(&mut self, iden: &DynIden) { - self.table_name = Some(format!("cte_{iden}").into_iden()) + self.table_name = Some(format!("cte_{iden}").into_iden()); } - /// Set up the columns of the CTE to match the given [SelectStatement] selected columns. + /// Set up the columns of the CTE to match the given [`SelectStatement`] selected columns. /// This will fail if the select contains non named columns like expressions of wildcards. /// /// Returns true if the column setup from the select query was successful. If the returned @@ -172,7 +174,7 @@ impl CommonTableExpression { } } -/// For recursive [WithQuery] [WithClause]s the traversing order can be specified in some databases +/// For recursive [`WithQuery`] [`WithClause`]s the traversing order can be specified in some databases /// that support this functionality. #[derive(Debug, Clone, PartialEq)] #[non_exhaustive] @@ -183,16 +185,16 @@ pub enum SearchOrder { DEPTH, } -/// For recursive [WithQuery] [WithClause]s the traversing order can be specified in some databases +/// For recursive [`WithQuery`] [`WithClause`]s the traversing order can be specified in some databases /// that support this functionality. /// -/// The clause contains the type of traversal: [SearchOrder] and the expression that is used to +/// The clause contains the type of traversal: [`SearchOrder`] and the expression that is used to /// construct the current path. /// /// A query can have both SEARCH and CYCLE clauses. /// -/// Setting [Self::order] and [Self::expr] is mandatory. The [SelectExpr] used must specify an alias -/// which will be the name that you can use to order the result of the [CommonTableExpression]. +/// Setting [`Self::order`] and [`Self::expr`] is mandatory. The [`SelectExpr`] used must specify an alias +/// which will be the name that you can use to order the result of the [`CommonTableExpression`]. #[derive(Debug, Clone, Default, PartialEq)] pub struct Search { pub(crate) order: Option, @@ -200,8 +202,11 @@ pub struct Search { } impl Search { - /// Create a complete [Search] specification from the [SearchOrder] and a [SelectExpr]. The - /// given [SelectExpr] must have an alias specified. + /// Create a complete [Search] specification from the [`SearchOrder`] and a [`SelectExpr`]. + /// + /// # Panics + /// + /// Panics if the given [`SelectExpr`] doesn't have an alias specified. pub fn new_from_order_and_expr(order: SearchOrder, expr: EXPR) -> Self where EXPR: Into, @@ -225,12 +230,16 @@ impl Search { self } - /// The given [SelectExpr] must have an alias specified. + /// The given [`SelectExpr`] must have an alias specified. /// /// The actual expression will be the one used to track the path in the graph. /// - /// The alias of the given [SelectExpr] will be the name of the order column generated by this + /// The alias of the given [`SelectExpr`] will be the name of the order column generated by this /// clause. + /// + /// # Panics + /// + /// Panics if the given [`SelectExpr`] doesn't have an alias specified. pub fn expr(&mut self, expr: EXPR) -> &mut Self where EXPR: Into, @@ -242,14 +251,14 @@ impl Search { } } -/// For recursive [WithQuery] [WithClauses](WithClause) the CYCLE sql clause can be specified to avoid creating +/// For recursive [`WithQuery`] [`WithClauses`](WithClause) the CYCLE sql clause can be specified to avoid creating /// an infinite traversals that loops on graph cycles indefinitely. /// /// You specify an expression that identifies a node in the graph, which is used during the query execution iteration, to determine newly appended values are distinct new nodes or are already visited, and therefore they should be added into the result again. /// /// A query can have both SEARCH and CYCLE clauses. /// -/// Setting [Self::set], [Self::expr] and [Self::using] is mandatory. +/// Setting [`Self::set`], [`Self::expr`] and [`Self::using`] is mandatory. #[derive(Debug, Clone, Default, PartialEq)] pub struct Cycle { pub(crate) expr: Option, @@ -258,8 +267,8 @@ pub struct Cycle { } impl Cycle { - /// Create a complete [Search] specification from the [SearchOrder] and a [SelectExpr]. The - /// given [SelectExpr] must have an alias specified. + /// Create a complete [Search] specification from the [`SearchOrder`] and a [`SelectExpr`]. The + /// given [`SelectExpr`] must have an alias specified. pub fn new_from_expr_set_using(expr: EXPR, set: ID1, using: ID2) -> Self where EXPR: Into, @@ -298,7 +307,7 @@ impl Cycle { } /// The name of the array typed column that contains the node ids (generated using the - /// [Self::expr]) that specify the current nodes path that will be generated by this clause. + /// [`Self::expr`]) that specify the current nodes path that will be generated by this clause. pub fn using(&mut self, using: ID) -> &mut Self where ID: IntoIden, @@ -308,26 +317,26 @@ impl Cycle { } } -/// A WITH clause can contain one or multiple common table expressions ([CommonTableExpression]). +/// A WITH clause can contain one or multiple common table expressions ([`CommonTableExpression`]). /// -/// You can use this to generate [WithQuery] by calling [WithClause::query]. +/// You can use this to generate [`WithQuery`] by calling [`WithClause::query`]. /// /// These named queries can act as a "query local table" that are materialized during execution and /// then can be used by the query prefixed with the WITH clause. /// -/// A WITH clause can contain multiple of these [CommonTableExpression]. (Except in the case of -/// recursive WITH query which can only contain one [CommonTableExpression]). +/// A WITH clause can contain multiple of these [`CommonTableExpression`]. (Except in the case of +/// recursive WITH query which can only contain one [`CommonTableExpression`]). /// -/// A [CommonTableExpression] is a name, column names and a query returning data for those columns. +/// A [`CommonTableExpression`] is a name, column names and a query returning data for those columns. /// /// Some databases (like sqlite) restrict the acceptable kinds of queries inside of the WITH clause -/// common table expressions. These databases only allow [SelectStatement]s to form a common table +/// common table expressions. These databases only allow [`SelectStatement`]s to form a common table /// expression. /// /// Other databases like postgres allow modification queries (UPDATE, DELETE) inside of the WITH /// clause but they have to return a table. (They must have a RETURNING clause). /// -/// sea-query doesn't check this or restrict the kind of [CommonTableExpression] that you can create +/// sea-query doesn't check this or restrict the kind of [`CommonTableExpression`] that you can create /// in rust. This means that you can put an UPDATE or DELETE queries into WITH clause and sea-query /// will succeed in generating that kind of sql query but the execution inside the database will /// fail because they are invalid. @@ -336,7 +345,7 @@ impl Cycle { /// sense and valid for that database that you are using. /// /// NOTE that for recursive WITH queries (in sql: "WITH RECURSIVE") you can only have a -/// single [CommonTableExpression] inside of the WITH clause. That query must match certain +/// single [`CommonTableExpression`] inside of the WITH clause. That query must match certain /// requirements: /// * It is a query of UNION or UNION ALL of two queries. /// * The first part of the query (the left side of the UNION) must be executable first in itself. @@ -344,11 +353,14 @@ impl Cycle { /// * The self reference must appear in the right hand side of the UNION. /// * The query can only have a single self-reference. /// * Recursive data-modifying statements are not supported, but you can use the results of a -/// recursive SELECT query in a data-modifying statement. (like so: WITH RECURSIVE -/// cte_name(a,b,c,d) AS (SELECT ... UNION SELECT ... FROM ... JOIN cte_name ON ... WHERE ...) -/// DELETE FROM table WHERE table.a = cte_name.a) +/// recursive SELECT query in a data-modifying statement. like so: +/// ```sql +/// WITH RECURSIVE +/// cte_name(a,b,c,d) AS (SELECT ... UNION SELECT ... FROM ... JOIN cte_name ON ... WHERE ...) +/// DELETE FROM table WHERE table.a = cte_name.a +/// ``` +/// It is mandatory to set the [`Self::cte`]. With queries must have at least one CTE. /// -/// It is mandatory to set the [Self::cte]. With queries must have at least one CTE. /// Recursive with query generation will panic if you specify more than one CTE. /// /// # Examples @@ -423,7 +435,7 @@ pub struct WithClause { } impl WithClause { - /// Constructs a new [WithClause]. + /// Constructs a new [`WithClause`]. pub fn new() -> Self { Self::default() } @@ -431,7 +443,7 @@ impl WithClause { /// Sets whether this clause is a recursive with clause of not. /// If set to true it will generate a 'WITH RECURSIVE' query. /// - /// You can only specify a single [CommonTableExpression] containing a union query + /// You can only specify a single [`CommonTableExpression`] containing a union query /// if this is set to true. pub fn recursive(&mut self, recursive: bool) -> &mut Self { self.recursive = recursive; @@ -458,13 +470,13 @@ impl WithClause { self } - /// Add a [CommonTableExpression] to this with clause. + /// Add a [`CommonTableExpression`] to this with clause. pub fn cte(&mut self, cte: CommonTableExpression) -> &mut Self { self.cte_expressions.push(cte); self } - /// You can turn this into a [WithQuery] using this function. The resulting WITH query will + /// You can turn this into a [`WithQuery`] using this function. The resulting WITH query will /// execute the argument query with this WITH clause. pub fn query(self, query: T) -> WithQuery where @@ -480,26 +492,26 @@ impl From for WithClause { } } -/// A WITH query. A simple SQL query that has a WITH clause ([WithClause]). +/// A WITH query. A simple SQL query that has a WITH clause ([`WithClause`]). /// -/// The [WithClause] can contain one or multiple common table expressions ([CommonTableExpression]). +/// The [`WithClause`] can contain one or multiple common table expressions ([`CommonTableExpression`]). /// /// These named queries can act as a "query local table" that are materialized during execution and /// then can be used by the query prefixed with the WITH clause. /// -/// A WITH clause can contain multiple of these [CommonTableExpression]. (Except in the case of -/// recursive WITH query which can only contain one [CommonTableExpression]). +/// A WITH clause can contain multiple of these [`CommonTableExpression`]. (Except in the case of +/// recursive WITH query which can only contain one [`CommonTableExpression`]). /// -/// A [CommonTableExpression] is a name, column names and a query returning data for those columns. +/// A [`CommonTableExpression`] is a name, column names and a query returning data for those columns. /// /// Some databases (like sqlite) restrict the acceptable kinds of queries inside of the WITH clause -/// common table expressions. These databases only allow [SelectStatement]s to form a common table +/// common table expressions. These databases only allow [`SelectStatement`]s to form a common table /// expression. /// /// Other databases like postgres allow modification queries (UPDATE, DELETE) inside of the WITH /// clause but they have to return a table. (They must have a RETURNING clause). /// -/// sea-query doesn't check this or restrict the kind of [CommonTableExpression] that you can create +/// sea-query doesn't check this or restrict the kind of [`CommonTableExpression`] that you can create /// in rust. This means that you can put an UPDATE or DELETE queries into WITH clause and sea-query /// will succeed in generating that kind of sql query but the execution inside the database will /// fail because they are invalid. @@ -508,7 +520,7 @@ impl From for WithClause { /// sense and valid for that database that you are using. /// /// NOTE that for recursive WITH queries (in sql: "WITH RECURSIVE") you can only have a -/// single [CommonTableExpression] inside of the WITH clause. That query must match certain +/// single [`CommonTableExpression`] inside of the WITH clause. That query must match certain /// requirements: /// * It is a query of UNION or UNION ALL of two queries. /// * The first part of the query (the left side of the UNION) must be executable first in itself. @@ -516,11 +528,15 @@ impl From for WithClause { /// * The self reference must appear in the right hand side of the UNION. /// * The query can only have a single self-reference. /// * Recursive data-modifying statements are not supported, but you can use the results of a -/// recursive SELECT query in a data-modifying statement. (like so: WITH RECURSIVE -/// cte_name(a,b,c,d) AS (SELECT ... UNION SELECT ... FROM ... JOIN cte_name ON ... WHERE ...) -/// DELETE FROM table WHERE table.a = cte_name.a) -/// -/// It is mandatory to set the [Self::cte] and the [Self::query]. +/// recursive SELECT query in a data-modifying statement. +/// like so: +/// ```sql +/// WITH RECURSIVE +/// cte_name(a,b,c,d) AS (SELECT ... UNION SELECT ... FROM ... JOIN cte_name ON ... WHERE ...) +/// DELETE FROM table WHERE table.a = cte_name.a +/// ``` +/// +/// It is mandatory to set the [`Self::cte`] and the [`Self::query`]. #[derive(Debug, Clone, Default, PartialEq)] pub struct WithQuery { pub(crate) with_clause: WithClause, @@ -528,42 +544,42 @@ pub struct WithQuery { } impl WithQuery { - /// Constructs a new empty [WithQuery]. + /// Constructs a new empty [`WithQuery`]. pub fn new() -> Self { Self::default() } - /// Set the whole [WithClause]. + /// Set the whole [`WithClause`]. pub fn with_clause(&mut self, with_clause: WithClause) -> &mut Self { self.with_clause = with_clause; self } - /// Set the [WithClause::recursive]. See that method for more information. + /// Set the [`WithClause::recursive`]. See that method for more information. pub fn recursive(&mut self, recursive: bool) -> &mut Self { self.with_clause.recursive = recursive; self } - /// Add the [WithClause::search]. See that method for more information. + /// Add the [`WithClause::search`]. See that method for more information. pub fn search(&mut self, search: Search) -> &mut Self { self.with_clause.search = Some(search); self } - /// Set the [WithClause::cycle]. See that method for more information. + /// Set the [`WithClause::cycle`]. See that method for more information. pub fn cycle(&mut self, cycle: Cycle) -> &mut Self { self.with_clause.cycle = Some(cycle); self } - /// Add a [CommonTableExpression] to the with clause. See [WithClause::cte]. + /// Add a [`CommonTableExpression`] to the with clause. See [`WithClause::cte`]. pub fn cte(&mut self, cte: CommonTableExpression) -> &mut Self { self.with_clause.cte_expressions.push(cte); self } - /// Set the query that you execute with the [WithClause]. + /// Set the query that you execute with the [`WithClause`]. pub fn query(&mut self, query: T) -> &mut Self where T: Into, diff --git a/src/raw_sql.rs b/src/raw_sql.rs index 343deb4e4..d5d3360c0 100644 --- a/src/raw_sql.rs +++ b/src/raw_sql.rs @@ -12,10 +12,14 @@ pub struct RawSqlQueryBuilder { } impl RawSqlQueryBuilder { + #[expect( + clippy::needless_pass_by_value, + reason = "Query builders are all zero-sized types" + )] pub fn new(backend: T) -> Self { let (placeholder, numbered) = backend.placeholder(); Self { - sql: Default::default(), + sql: String::default(), parameter_index: 1, placeholder, numbered, @@ -91,18 +95,18 @@ mod test { .push_fragment(" ") .push_parameters(1) .push_fragment(", ") - .push_parameters((&b).len()) + .push_parameters(b.len()) .push_fragment(", ") - .push_parameters((&c).len()); + .push_parameters(c.len()); assert_eq!(builder.finish(), "SELECT $1, $2, $3, $4, $5, $6"); let mut values = Values::default(); values.bind(a); - for v in (&b).iter() { + for v in &b { values.bind(v); } - for v in (&c).iter() { + for v in &c { values.bind(v); } diff --git a/src/raw_sql/seaql.rs b/src/raw_sql/seaql.rs index 37837bdc2..93574a98c 100644 --- a/src/raw_sql/seaql.rs +++ b/src/raw_sql/seaql.rs @@ -9,7 +9,7 @@ pub struct Query { pub fn query(sql: &str) -> Query { Query { sql: sql.to_owned(), - values: Values(Default::default()), + values: Values(Vec::default()), } } @@ -33,7 +33,7 @@ pub struct DebugQuery { pub fn debug(sql: &str) -> DebugQuery { DebugQuery { sql: sql.to_owned(), - params: Default::default(), + params: Vec::default(), } } diff --git a/src/table/column.rs b/src/table/column.rs index 6c2ea2c97..0f7af32ca 100644 --- a/src/table/column.rs +++ b/src/table/column.rs @@ -117,15 +117,13 @@ pub enum StringLen { impl PartialEq for ColumnType { fn eq(&self, other: &Self) -> bool { match (self, other) { - (Self::Char(l0), Self::Char(r0)) => l0 == r0, - (Self::String(l0), Self::String(r0)) => l0 == r0, - (Self::Decimal(l0), Self::Decimal(r0)) => l0 == r0, + (Self::String(l0), Self::String(r0)) | (Self::VarBinary(l0), Self::VarBinary(r0)) => { + l0 == r0 + } + (Self::Decimal(l0), Self::Decimal(r0)) | (Self::Money(l0), Self::Money(r0)) => l0 == r0, (Self::Interval(l0, l1), Self::Interval(r0, r1)) => l0 == r0 && l1 == r1, - (Self::Binary(l0), Self::Binary(r0)) => l0 == r0, - (Self::VarBinary(l0), Self::VarBinary(r0)) => l0 == r0, - (Self::Bit(l0), Self::Bit(r0)) => l0 == r0, - (Self::VarBit(l0), Self::VarBit(r0)) => l0 == r0, - (Self::Money(l0), Self::Money(r0)) => l0 == r0, + (Self::Binary(l0), Self::Binary(r0)) | (Self::VarBit(l0), Self::VarBit(r0)) => l0 == r0, + (Self::Bit(l0), Self::Bit(r0)) | (Self::Char(l0), Self::Char(r0)) => l0 == r0, (Self::Custom(l0), Self::Custom(r0)) => l0.to_string() == r0.to_string(), ( Self::Enum { @@ -140,8 +138,8 @@ impl PartialEq for ColumnType { l_name.to_string() == r_name.to_string() && l_variants .iter() - .map(|v| v.to_string()) - .eq(r_variants.iter().map(|v| v.to_string())) + .map(ToString::to_string) + .eq(r_variants.iter().map(ToString::to_string)) } (Self::Array(l0), Self::Array(r0)) => l0 == r0, _ => core::mem::discriminant(self) == core::mem::discriminant(other), @@ -187,7 +185,7 @@ pub enum ColumnSpec { } // All interval fields -#[derive(Debug, Clone, Eq, PartialEq)] +#[derive(Debug, Clone, Copy, Eq, PartialEq)] #[non_exhaustive] pub enum PgInterval { Year, @@ -206,7 +204,7 @@ pub enum PgInterval { } // All possible inputs to DATE_TRUNC (https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC) -#[derive(Debug, Clone, Eq, PartialEq)] +#[derive(Debug, Clone, Copy, Eq, PartialEq)] #[non_exhaustive] pub enum PgDateTruncUnit { Microseconds, @@ -368,7 +366,7 @@ impl ColumnDef { /// Set column type as string pub fn string(&mut self) -> &mut Self { - self.types = Some(ColumnType::String(Default::default())); + self.types = Some(ColumnType::String(StringLen::default())); self } @@ -378,13 +376,13 @@ impl ColumnDef { self } - /// Set column type as tiny_integer + /// Set column type as tiny integer pub fn tiny_integer(&mut self) -> &mut Self { self.types = Some(ColumnType::TinyInteger); self } - /// Set column type as small_integer + /// Set column type as small integer pub fn small_integer(&mut self) -> &mut Self { self.types = Some(ColumnType::SmallInteger); self @@ -396,19 +394,19 @@ impl ColumnDef { self } - /// Set column type as big_integer + /// Set column type as big integer pub fn big_integer(&mut self) -> &mut Self { self.types = Some(ColumnType::BigInteger); self } - /// Set column type as tiny_unsigned + /// Set column type as tiny unsigned pub fn tiny_unsigned(&mut self) -> &mut Self { self.types = Some(ColumnType::TinyUnsigned); self } - /// Set column type as small_unsigned + /// Set column type as small unsigned pub fn small_unsigned(&mut self) -> &mut Self { self.types = Some(ColumnType::SmallUnsigned); self @@ -420,7 +418,7 @@ impl ColumnDef { self } - /// Set column type as big_unsigned + /// Set column type as big unsigned pub fn big_unsigned(&mut self) -> &mut Self { self.types = Some(ColumnType::BigUnsigned); self @@ -450,7 +448,7 @@ impl ColumnDef { self } - /// Set column type as date_time + /// Set column type as date time pub fn date_time(&mut self) -> &mut Self { self.types = Some(ColumnType::DateTime); self diff --git a/src/table/create.rs b/src/table/create.rs index 3dc1049a4..51fe129d5 100644 --- a/src/table/create.rs +++ b/src/table/create.rs @@ -300,7 +300,7 @@ impl TableCreateStatement { } /// Rewriting extra param. You should take care self about concat extra params. Add extra after options. - /// Example for PostgresSQL [Citus](https://github.com/citusdata/citus) extension: + /// Example for PostgreSQL [Citus](https://github.com/citusdata/citus) extension: /// ``` /// use sea_query::{tests_cfg::*, *}; /// let table = Table::create() @@ -348,10 +348,10 @@ impl TableCreateStatement { /// Create temporary table /// /// Ref: - /// - PostgreSQL: https://www.postgresql.org/docs/17/sql-createtable.html#SQL-CREATETABLE-TEMPORARY - /// - MySQL: https://dev.mysql.com/doc/refman/9.2/en/create-temporary-table.html - /// - MariaDB: https://mariadb.com/kb/en/create-table/#create-temporary-table - /// - SQLite: https://sqlite.org/lang_createtable.html + /// - PostgreSQL: + /// - MySQL: + /// - MariaDB: + /// - SQLite: /// /// # Examples /// diff --git a/src/tests_cfg.rs b/src/tests_cfg.rs index 256249cf8..ff1d290db 100644 --- a/src/tests_cfg.rs +++ b/src/tests_cfg.rs @@ -30,9 +30,8 @@ pub type Char = Character; impl Iden for Character { fn unquoted(&self) -> &str { match self { - Self::Table => "character", Self::Id => "id", - Self::Character => "character", + Self::Character | Self::Table => "character", Self::FontSize => "font_size", Self::SizeW => "size_w", Self::SizeH => "size_h", diff --git a/src/token.rs b/src/token.rs index f06851cfe..bebb91456 100644 --- a/src/token.rs +++ b/src/token.rs @@ -68,10 +68,10 @@ impl<'a> Tokenizer<'a> { self.inc(); } - if a != b { - Some(Token::Space(&self.input[a..b])) - } else { + if a == b { None + } else { + Some(Token::Space(&self.input[a..b])) } } @@ -94,10 +94,10 @@ impl<'a> Tokenizer<'a> { } } - if a != b { - Some(Token::Unquoted(&self.input[a..b])) - } else { + if a == b { None + } else { + Some(Token::Unquoted(&self.input[a..b])) } } @@ -121,11 +121,11 @@ impl<'a> Tokenizer<'a> { if self.end() { break; } - if !Self::is_string_escape_for(start, self.get()) { - break; - } else { + if Self::is_string_escape_for(start, self.get()) { b = self.p_c(c); self.inc(); + } else { + break; } } else if !first { escape = !escape && Self::is_escape_char(c); @@ -135,10 +135,10 @@ impl<'a> Tokenizer<'a> { break; } } - if a != b { - Some(Token::Quoted(&self.input[a..b])) - } else { + if a == b { None + } else { + Some(Token::Quoted(&self.input[a..b])) } } @@ -159,11 +159,11 @@ impl<'a> Tokenizer<'a> { if self.end() { break; } - if !Self::is_string_escape_for(start, self.get()) { - break; - } else { + if Self::is_string_escape_for(start, self.get()) { write!(string, "{c}").unwrap(); self.inc(); + } else { + break; } } else if !first { escape = !escape && Self::is_escape_char(c); @@ -188,10 +188,10 @@ impl<'a> Tokenizer<'a> { } } - if a != b { - Some(Token::Punctuation(&self.input[a..b])) - } else { + if a == b { None + } else { + Some(Token::Punctuation(&self.input[a..b])) } } @@ -274,10 +274,10 @@ impl Token<'_> { pub fn as_str(&self) -> &str { match self { - Self::Quoted(string) => string, - Self::Unquoted(string) => string, - Self::Space(string) => string, - Self::Punctuation(string) => string, + Self::Quoted(string) + | Self::Unquoted(string) + | Self::Space(string) + | Self::Punctuation(string) => string, } } @@ -293,16 +293,7 @@ impl Token<'_> { impl std::fmt::Display for Token<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "{}", - match self { - Token::Unquoted(string) => string, - Token::Space(string) => string, - Token::Quoted(string) => string, - Token::Punctuation(string) => string, - } - ) + f.write_str(self.as_str()) } } @@ -336,7 +327,7 @@ mod tests { ); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -367,7 +358,7 @@ mod tests { ); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -389,7 +380,7 @@ mod tests { ); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -401,7 +392,7 @@ mod tests { assert_eq!(tokens, vec![Token::Quoted("\"a\\\"bc\"")]); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -413,7 +404,7 @@ mod tests { assert_eq!(tokens, vec![Token::Unquoted(string)]); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -434,7 +425,7 @@ mod tests { ); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -453,7 +444,7 @@ mod tests { ); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -465,7 +456,7 @@ mod tests { assert_eq!(tokens, vec![Token::Quoted("`a\"b`"), Token::Space(" ")]); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -477,7 +468,7 @@ mod tests { assert_eq!(tokens, vec![Token::Quoted("[ab]"), Token::Space(" ")]); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -496,7 +487,7 @@ mod tests { ); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -515,7 +506,7 @@ mod tests { ); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -534,7 +525,7 @@ mod tests { ); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -553,7 +544,7 @@ mod tests { ); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -578,7 +569,7 @@ mod tests { ); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -597,7 +588,7 @@ mod tests { ); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -609,7 +600,7 @@ mod tests { assert_eq!(tokens, vec![Token::Unquoted(string)]); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -624,7 +615,7 @@ mod tests { ); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -643,7 +634,7 @@ mod tests { ); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -684,7 +675,7 @@ mod tests { ); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -705,7 +696,7 @@ mod tests { ); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -724,7 +715,7 @@ mod tests { ); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -747,7 +738,7 @@ mod tests { ); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } @@ -774,7 +765,7 @@ mod tests { ); assert_eq!( string, - tokens.iter().map(|x| x.as_str()).collect::() + tokens.iter().map(super::Token::as_str).collect::() ); } } diff --git a/src/types.rs b/src/types.rs index 4e2092f9f..dac020e2d 100644 --- a/src/types.rs +++ b/src/types.rs @@ -28,12 +28,12 @@ pub struct Quote(pub(crate) u8, pub(crate) u8); pub trait Iden { /// Return the to-be sanitized version of the identifier. /// - /// For example, for MySQL "hel`lo`" would have to be escaped as "hel``lo". + /// For example, for MySQL "hel\`lo\`" would have to be escaped as "hel\`\`lo". /// Note that this method doesn't do the actual escape, /// as it's backend specific. /// It only indicates whether the identifier needs to be escaped. /// - /// If the identifier doesn't need to be escaped, return `'static str`. + /// If the identifier doesn't need to be escaped, return `&'static str`. /// This can be deduced at compile-time by the `Iden` macro, /// or using the [`is_static_iden`] function. /// @@ -100,6 +100,7 @@ impl SeaRc { /// Note that most `Iden`s are statically known /// and their representations aren't actually "rendered" and allocated at runtime. #[allow(clippy::new_ret_no_self)] + #[expect(clippy::needless_pass_by_value, reason = "compatibility")] pub fn new(i: I) -> DynIden where I: Iden, @@ -440,6 +441,7 @@ pub trait IntoLikeExpr { fn into_like_expr(self) -> LikeExpr; } +#[expect(clippy::doc_markdown)] /// SubQuery operators #[derive(Debug, Copy, Clone, PartialEq)] #[non_exhaustive] @@ -776,7 +778,7 @@ impl NullAlias { } impl Iden for NullAlias { - fn unquoted(&self) -> &str { + fn unquoted(&self) -> &'static str { "" } } diff --git a/src/value.rs b/src/value.rs index ac47b9837..d134e760b 100644 --- a/src/value.rs +++ b/src/value.rs @@ -481,6 +481,11 @@ impl Value { /// let n = v.dummy_value(); /// assert_eq!(n, Value::Int(Some(0))); /// ``` + /// + /// # Panics + /// + /// Panics if parse "0.0.0.0" to [`IpNetwork`] fails. + #[expect(clippy::default_trait_access, reason = "Consistency")] pub fn dummy_value(&self) -> Self { match self { Self::Bool(_) => Self::Bool(Some(Default::default())), diff --git a/src/value/hashable_value.rs b/src/value/hashable_value.rs index e51a9234d..34430456a 100644 --- a/src/value/hashable_value.rs +++ b/src/value/hashable_value.rs @@ -17,14 +17,14 @@ impl PartialEq for Value { (Self::SmallUnsigned(l), Self::SmallUnsigned(r)) => l == r, (Self::Unsigned(l), Self::Unsigned(r)) => l == r, (Self::BigUnsigned(l), Self::BigUnsigned(r)) => l == r, - (Self::Float(l), Self::Float(r)) => cmp_f32(l, r), - (Self::Double(l), Self::Double(r)) => cmp_f64(l, r), + (Self::Float(l), Self::Float(r)) => cmp_f32(l.as_ref(), r.as_ref()), + (Self::Double(l), Self::Double(r)) => cmp_f64(l.as_ref(), r.as_ref()), (Self::String(l), Self::String(r)) => l == r, (Self::Char(l), Self::Char(r)) => l == r, (Self::Bytes(l), Self::Bytes(r)) => l == r, #[cfg(feature = "with-json")] - (Self::Json(l), Self::Json(r)) => cmp_json(l, r), + (Self::Json(l), Self::Json(r)) => cmp_json(l.as_ref(), r.as_ref()), #[cfg(feature = "with-chrono")] (Self::ChronoDate(l), Self::ChronoDate(r)) => l == r, @@ -74,7 +74,7 @@ impl PartialEq for Value { } #[cfg(feature = "postgres-vector")] - (Self::Vector(l), Self::Vector(r)) => cmp_vector(l, r), + (Self::Vector(l), Self::Vector(r)) => cmp_vector(l.as_ref(), r.as_ref()), #[cfg(feature = "with-ipnetwork")] (Self::IpNetwork(l), Self::IpNetwork(r)) => l == r, @@ -102,14 +102,14 @@ impl Hash for Value { Value::SmallUnsigned(v) => v.hash(state), Value::Unsigned(v) => v.hash(state), Value::BigUnsigned(v) => v.hash(state), - Value::Float(v) => hash_f32(v, state), - Value::Double(v) => hash_f64(v, state), + Value::Float(v) => hash_f32(v.as_ref(), state), + Value::Double(v) => hash_f64(v.as_ref(), state), Value::String(v) => v.hash(state), Value::Char(v) => v.hash(state), Value::Bytes(v) => v.hash(state), #[cfg(feature = "with-json")] - Value::Json(value) => hash_json(value, state), + Value::Json(value) => hash_json(value.as_ref(), state), #[cfg(feature = "with-chrono")] Value::ChronoDate(naive_date) => naive_date.hash(state), @@ -160,7 +160,7 @@ impl Hash for Value { } #[cfg(feature = "postgres-vector")] - Value::Vector(vector) => hash_vector(vector, state), + Value::Vector(vector) => hash_vector(vector.as_ref(), state), #[cfg(feature = "with-ipnetwork")] Value::IpNetwork(ip_network) => ip_network.hash(state), @@ -171,21 +171,21 @@ impl Hash for Value { } } -fn hash_f32(v: &Option, state: &mut H) { +fn hash_f32(v: Option<&f32>, state: &mut H) { match v { Some(v) => OrderedFloat(*v).hash(state), None => "null".hash(state), } } -fn hash_f64(v: &Option, state: &mut H) { +fn hash_f64(v: Option<&f64>, state: &mut H) { match v { Some(v) => OrderedFloat(*v).hash(state), None => "null".hash(state), } } -fn cmp_f32(l: &Option, r: &Option) -> bool { +fn cmp_f32(l: Option<&f32>, r: Option<&f32>) -> bool { match (l, r) { (Some(l), Some(r)) => OrderedFloat(*l).eq(&OrderedFloat(*r)), (None, None) => true, @@ -193,7 +193,7 @@ fn cmp_f32(l: &Option, r: &Option) -> bool { } } -fn cmp_f64(l: &Option, r: &Option) -> bool { +fn cmp_f64(l: Option<&f64>, r: Option<&f64>) -> bool { match (l, r) { (Some(l), Some(r)) => OrderedFloat(*l).eq(&OrderedFloat(*r)), (None, None) => true, @@ -202,7 +202,7 @@ fn cmp_f64(l: &Option, r: &Option) -> bool { } #[cfg(feature = "with-json")] -fn hash_json(v: &Option, state: &mut H) { +fn hash_json(v: Option<&Json>, state: &mut H) { match v { Some(v) => serde_json::to_string(v).unwrap().hash(state), None => "null".hash(state), @@ -210,7 +210,7 @@ fn hash_json(v: &Option, state: &mut H) { } #[cfg(feature = "with-json")] -fn cmp_json(l: &Option, r: &Option) -> bool { +fn cmp_json(l: Option<&Json>, r: Option<&Json>) -> bool { match (l, r) { (Some(l), Some(r)) => serde_json::to_string(l) .unwrap() @@ -221,11 +221,11 @@ fn cmp_json(l: &Option, r: &Option) -> bool { } #[cfg(feature = "postgres-vector")] -fn hash_vector(v: &Option, state: &mut H) { +fn hash_vector(v: Option<&pgvector::Vector>, state: &mut H) { match v { Some(v) => { - for &value in v.as_slice().iter() { - hash_f32(&Some(value), state); + for &value in v.as_slice() { + hash_f32(Some(&value), state); } } None => "null".hash(state), @@ -233,7 +233,7 @@ fn hash_vector(v: &Option, state: &mut H) { } #[cfg(feature = "postgres-vector")] -fn cmp_vector(l: &Option, r: &Option) -> bool { +fn cmp_vector(l: Option<&pgvector::Vector>, r: Option<&pgvector::Vector>) -> bool { match (l, r) { (Some(l), Some(r)) => { let (l, r) = (l.as_slice(), r.as_slice()); @@ -241,7 +241,7 @@ fn cmp_vector(l: &Option, r: &Option) -> boo return false; } for (l, r) in l.iter().zip(r.iter()) { - if !cmp_f32(&Some(*l), &Some(*r)) { + if !cmp_f32(Some(l), Some(r)) { return false; } } diff --git a/src/value/with_array.rs b/src/value/with_array.rs index ef198974f..4410cb5c3 100644 --- a/src/value/with_array.rs +++ b/src/value/with_array.rs @@ -83,7 +83,7 @@ where fn from(x: Vec) -> Value { Value::Array( T::array_type(), - Some(Box::new(x.into_iter().map(|e| e.into()).collect())), + Some(Box::new(x.into_iter().map(Into::into).collect())), ) } } @@ -104,7 +104,7 @@ where fn try_from(v: Value) -> Result { match v { Value::Array(ty, Some(v)) if T::array_type() == ty => { - Ok(v.into_iter().map(|e| e.unwrap()).collect()) + Ok(v.into_iter().map(super::Value::unwrap).collect()) } _ => Err(ValueTypeErr), } @@ -129,9 +129,12 @@ impl Value { matches!(self, Self::Array(_, _)) } + /// # Panics + /// + /// Panics if self is not [`Value::Array`] pub fn as_ref_array(&self) -> Option<&Vec> { match self { - Self::Array(_, v) => v.as_ref().map(|v| v.as_ref()), + Self::Array(_, v) => v.as_ref().map(AsRef::as_ref), _ => panic!("not Value::Array"), } } diff --git a/src/value/with_bigdecimal.rs b/src/value/with_bigdecimal.rs index 9a7ee4264..75e9d4f39 100644 --- a/src/value/with_bigdecimal.rs +++ b/src/value/with_bigdecimal.rs @@ -7,13 +7,19 @@ impl Value { matches!(self, Self::BigDecimal(_)) } + /// # Panics + /// + /// Panics if self is not [`Value::BigDecimal`] pub fn as_ref_big_decimal(&self) -> Option<&BigDecimal> { match self { - Self::BigDecimal(v) => v.as_ref().map(|x| x.as_ref()), + Self::BigDecimal(v) => v.as_ref().map(AsRef::as_ref), _ => panic!("not Value::BigDecimal"), } } + /// # Panics + /// + /// Panics if the conversion to [`f64`] fails pub fn big_decimal_to_f64(&self) -> Option { use bigdecimal::ToPrimitive; self.as_ref_big_decimal().map(|d| d.to_f64().unwrap()) diff --git a/src/value/with_chrono.rs b/src/value/with_chrono.rs index 9e95f5c76..a251c3288 100644 --- a/src/value/with_chrono.rs +++ b/src/value/with_chrono.rs @@ -130,6 +130,9 @@ impl Value { matches!(self, Self::ChronoDateTimeLocal(_)) } + /// # Panics + /// + /// Panics if self is not [`Value::ChronoDate`] pub fn as_ref_chrono_date(&self) -> Option<&NaiveDate> { match self { Self::ChronoDate(v) => v.as_ref(), @@ -137,6 +140,9 @@ impl Value { } } + /// # Panics + /// + /// Panics if self is not [`Value::ChronoTime`] pub fn as_ref_chrono_time(&self) -> Option<&NaiveTime> { match self { Self::ChronoTime(v) => v.as_ref(), @@ -144,6 +150,9 @@ impl Value { } } + /// # Panics + /// + /// Panics if self is not [`Value::ChronoDateTime`] pub fn as_ref_chrono_date_time(&self) -> Option<&NaiveDateTime> { match self { Self::ChronoDateTime(v) => v.as_ref(), @@ -151,6 +160,9 @@ impl Value { } } + /// # Panics + /// + /// Panics if self is not [`Value::ChronoDateTimeUtc`] pub fn as_ref_chrono_date_time_utc(&self) -> Option<&DateTime> { match self { Self::ChronoDateTimeUtc(v) => v.as_ref(), @@ -158,6 +170,9 @@ impl Value { } } + /// # Panics + /// + /// Panics if self is not [`Value::ChronoDateTimeWithTimeZone`] pub fn as_ref_chrono_date_time_with_time_zone(&self) -> Option<&DateTime> { match self { Self::ChronoDateTimeWithTimeZone(v) => v.as_ref(), @@ -165,6 +180,9 @@ impl Value { } } + /// # Panics + /// + /// Panics if self is not [`Value::ChronoDateTimeLocal`] pub fn as_ref_chrono_date_time_local(&self) -> Option<&DateTime> { match self { Self::ChronoDateTimeLocal(v) => v.as_ref(), @@ -172,11 +190,14 @@ impl Value { } } + /// # Panics + /// + /// Panics if self is not a time value from [`chrono`] crate pub fn chrono_as_naive_utc_in_string(&self) -> Option { match self { - Self::ChronoDate(v) => v.as_ref().map(|v| v.to_string()), - Self::ChronoTime(v) => v.as_ref().map(|v| v.to_string()), - Self::ChronoDateTime(v) => v.as_ref().map(|v| v.to_string()), + Self::ChronoDate(v) => v.as_ref().map(ToString::to_string), + Self::ChronoTime(v) => v.as_ref().map(ToString::to_string), + Self::ChronoDateTime(v) => v.as_ref().map(ToString::to_string), Self::ChronoDateTimeUtc(v) => v.as_ref().map(|v| v.naive_utc().to_string()), Self::ChronoDateTimeLocal(v) => v.as_ref().map(|v| v.naive_utc().to_string()), Self::ChronoDateTimeWithTimeZone(v) => v.as_ref().map(|v| v.naive_utc().to_string()), diff --git a/src/value/with_ipnetwork.rs b/src/value/with_ipnetwork.rs index 42eaffed0..440c1979b 100644 --- a/src/value/with_ipnetwork.rs +++ b/src/value/with_ipnetwork.rs @@ -7,6 +7,9 @@ impl Value { matches!(self, Self::IpNetwork(_)) } + /// # Panics + /// + /// Panics if self is not [`Value::IpNetwork`] pub fn as_ref_ipnetwork(&self) -> Option<&IpNetwork> { match self { Self::IpNetwork(v) => v.as_ref(), @@ -14,9 +17,12 @@ impl Value { } } + /// # Panics + /// + /// Panics if self is not [`Value::IpNetwork`] pub fn as_ipaddr(&self) -> Option { match self { - Self::IpNetwork(v) => v.as_ref().map(|v| v.network()), + Self::IpNetwork(v) => v.as_ref().map(ipnetwork::IpNetwork::network), _ => panic!("not Value::IpNetwork"), } } diff --git a/src/value/with_jiff.rs b/src/value/with_jiff.rs index c072f8f07..dbcae754d 100644 --- a/src/value/with_jiff.rs +++ b/src/value/with_jiff.rs @@ -55,6 +55,9 @@ impl Value { matches!(self, Self::JiffZoned(_)) } + /// # Panics + /// + /// Panics if self is not [`Value::JiffDate`] pub fn as_ref_jiff_date(&self) -> Option<&civil::Date> { match self { Self::JiffDate(v) => v.as_ref(), @@ -62,6 +65,9 @@ impl Value { } } + /// # Panics + /// + /// Panics if self is not [`Value::JiffTime`] pub fn as_ref_jiff_time(&self) -> Option<&civil::Time> { match self { Self::JiffTime(v) => v.as_ref(), @@ -69,6 +75,9 @@ impl Value { } } + /// # Panics + /// + /// Panics if self is not [`Value::JiffDateTime`] pub fn as_ref_jiff_date_time(&self) -> Option<&civil::DateTime> { match self { Self::JiffDateTime(v) => v.as_deref(), @@ -76,6 +85,9 @@ impl Value { } } + /// # Panics + /// + /// Panics if self is not [`Value::JiffTimestamp`] pub fn as_ref_jiff_timestamp(&self) -> Option<&Timestamp> { match self { Self::JiffTimestamp(v) => v.as_deref(), @@ -83,6 +95,9 @@ impl Value { } } + /// # Panics + /// + /// Panics if self is not [`Value::JiffZoned`] pub fn as_ref_jiff_zoned(&self) -> Option<&Zoned> { match self { Self::JiffZoned(v) => v.as_deref(), @@ -99,8 +114,8 @@ impl Value { #[cfg(test)] pub(crate) fn jiff_value_to_string(&self) -> Option { match self { - Self::JiffDate(v) => v.as_ref().map(|v| v.to_string()), - Self::JiffTime(v) => v.as_ref().map(|v| v.to_string()), + Self::JiffDate(v) => v.as_ref().map(ToString::to_string), + Self::JiffTime(v) => v.as_ref().map(ToString::to_string), Self::JiffDateTime(v) => v .as_ref() .map(|v| v.strftime(JIFF_DATE_TIME_FMT_STR).to_string()), diff --git a/src/value/with_json.rs b/src/value/with_json.rs index 7b4cf4ba6..90c7b7deb 100644 --- a/src/value/with_json.rs +++ b/src/value/with_json.rs @@ -7,6 +7,9 @@ impl Value { matches!(self, Self::Json(_)) } + /// # Panics + /// + /// Panics if self is not [`Value::Json`] pub fn as_ref_json(&self) -> Option<&Json> { match self { Self::Json(v) => v.as_ref(), @@ -16,6 +19,10 @@ impl Value { } /// Convert value to json value +/// +/// # Panics +/// +/// Panics if value is [`Value::Bytes`] and it's not valid utf-8 #[allow(clippy::many_single_char_names)] pub fn sea_value_to_json_value(value: &Value) -> Json { match value { diff --git a/src/value/with_mac_address.rs b/src/value/with_mac_address.rs index 834695b31..7816ce717 100644 --- a/src/value/with_mac_address.rs +++ b/src/value/with_mac_address.rs @@ -7,6 +7,9 @@ impl Value { matches!(self, Self::MacAddress(_)) } + /// # Panics + /// + /// Panics if self is not [`Value::MacAddress`] pub fn as_ref_mac_address(&self) -> Option<&MacAddress> { match self { Self::MacAddress(v) => v.as_ref(), diff --git a/src/value/with_rust_decimal.rs b/src/value/with_rust_decimal.rs index 7733a8ebd..18152ee80 100644 --- a/src/value/with_rust_decimal.rs +++ b/src/value/with_rust_decimal.rs @@ -7,6 +7,9 @@ impl Value { matches!(self, Self::Decimal(_)) } + /// # Panics + /// + /// Panics if self is not [`Value::Decimal`] pub fn as_ref_decimal(&self) -> Option<&Decimal> { match self { Self::Decimal(v) => v.as_ref(), @@ -14,6 +17,9 @@ impl Value { } } + /// # Panics + /// + /// Panics if the conversion to [`f64`] fails pub fn decimal_to_f64(&self) -> Option { use rust_decimal::prelude::ToPrimitive; diff --git a/src/value/with_time.rs b/src/value/with_time.rs index 5ea29c6f1..b4f33e52f 100644 --- a/src/value/with_time.rs +++ b/src/value/with_time.rs @@ -42,6 +42,9 @@ impl Value { matches!(self, Self::TimeDate(_)) } + /// # Panics + /// + /// Panics if self is not [`Value::TimeDate`] pub fn as_ref_time_date(&self) -> Option<&time::Date> { match self { Self::TimeDate(v) => v.as_ref(), @@ -55,6 +58,9 @@ impl Value { matches!(self, Self::TimeTime(_)) } + /// # Panics + /// + /// Panics if self is not [`Value::TimeTime`] pub fn as_ref_time_time(&self) -> Option<&time::Time> { match self { Self::TimeTime(v) => v.as_ref(), @@ -68,6 +74,9 @@ impl Value { matches!(self, Self::TimeDateTime(_)) } + /// # Panics + /// + /// Panics if self is not [`Value::TimeDateTime`] pub fn as_ref_time_date_time(&self) -> Option<&PrimitiveDateTime> { match self { Self::TimeDateTime(v) => v.as_ref(), @@ -81,6 +90,9 @@ impl Value { matches!(self, Self::TimeDateTimeWithTimeZone(_)) } + /// # Panics + /// + /// Panics if self is not [`Value::TimeDateTimeWithTimeZone`] pub fn as_ref_time_date_time_with_time_zone(&self) -> Option<&OffsetDateTime> { match self { Self::TimeDateTimeWithTimeZone(v) => v.as_ref(), @@ -90,6 +102,9 @@ impl Value { } impl Value { + /// # Panics + /// + /// Panics if self is not a time value from [`time`] crate pub fn time_as_naive_utc_in_string(&self) -> Option { match self { Self::TimeDate(v) => v diff --git a/src/value/with_uuid.rs b/src/value/with_uuid.rs index c12a8b102..53807b755 100644 --- a/src/value/with_uuid.rs +++ b/src/value/with_uuid.rs @@ -48,6 +48,10 @@ impl Value { pub fn is_uuid(&self) -> bool { matches!(self, Self::Uuid(_)) } + + /// # Panics + /// + /// Panics if self is not [`Value::Uuid`] pub fn as_ref_uuid(&self) -> Option<&Uuid> { match self { Self::Uuid(v) => v.as_ref(), diff --git a/tests/mysql/query.rs b/tests/mysql/query.rs index 255a00837..b1415a7c9 100644 --- a/tests/mysql/query.rs +++ b/tests/mysql/query.rs @@ -736,7 +736,7 @@ fn select_48() { .from(Glyph::Table) .cond_where( Cond::all().add_option(Some( - Expr::tuple([Expr::col(Glyph::Aspect).into(), Expr::value(100)]) + Expr::tuple([Expr::col(Glyph::Aspect), Expr::value(100)]) .lt(Expr::tuple([Expr::value(8), Expr::value(100)])), )), ) @@ -755,11 +755,8 @@ fn select_48a() { .from(Glyph::Table) .cond_where( Cond::all().add_option(Some( - Expr::tuple([ - Expr::col(Glyph::Aspect).into(), - Expr::value(String::from("100")), - ]) - .in_tuples([(8, String::from("100"))]), + Expr::tuple([Expr::col(Glyph::Aspect), Expr::value(String::from("100"))]) + .in_tuples([(8, String::from("100"))]), )), ) .to_string(MysqlQueryBuilder); diff --git a/tests/postgres/query.rs b/tests/postgres/query.rs index c9ec7d8fe..499d9facc 100644 --- a/tests/postgres/query.rs +++ b/tests/postgres/query.rs @@ -822,7 +822,7 @@ fn select_48() { .from(Glyph::Table) .cond_where( Cond::all().add_option(Some( - Expr::tuple([Expr::col(Glyph::Aspect).into(), Expr::value(100)]) + Expr::tuple([Expr::col(Glyph::Aspect), Expr::value(100)]) .lt(Expr::tuple([Expr::value(8), Expr::value(100)])), )), ) @@ -841,11 +841,8 @@ fn select_48a() { .from(Glyph::Table) .cond_where( Cond::all().add_option(Some( - Expr::tuple([ - Expr::col(Glyph::Aspect).into(), - Expr::value(String::from("100")), - ]) - .in_tuples([(8, String::from("100"))]), + Expr::tuple([Expr::col(Glyph::Aspect), Expr::value(String::from("100"))]) + .in_tuples([(8, String::from("100"))]), )), ) .to_string(PostgresQueryBuilder); diff --git a/tests/sqlite/query.rs b/tests/sqlite/query.rs index 6bb781920..a82c2d4e6 100644 --- a/tests/sqlite/query.rs +++ b/tests/sqlite/query.rs @@ -737,7 +737,7 @@ fn select_48() { .from(Glyph::Table) .cond_where( Cond::all().add_option(Some( - Expr::tuple([Expr::col(Glyph::Aspect).into(), Expr::value(100)]) + Expr::tuple([Expr::col(Glyph::Aspect), Expr::value(100)]) .lt(Expr::tuple([Expr::value(8), Expr::value(100)])), )), ) @@ -756,11 +756,8 @@ fn select_48a() { .from(Glyph::Table) .cond_where( Cond::all().add_option(Some( - Expr::tuple([ - Expr::col(Glyph::Aspect).into(), - Expr::value(String::from("100")), - ]) - .in_tuples([(8, String::from("100"))]), + Expr::tuple([Expr::col(Glyph::Aspect), Expr::value(String::from("100"))]) + .in_tuples([(8, String::from("100"))]), )), ) .to_string(SqliteQueryBuilder);