{"record":{"id":"a61071b317c0b889","repo":"diesel-rs/diesel","slug":"tuples-should-never-implement-tosql-directly","errorCode":null,"errorMessage":"Tuples should never implement `ToSql` directly","messagePattern":"Tuples should never implement `ToSql` directly","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"diesel/src/type_impls/tuples.rs","lineNumber":59,"sourceCode":"        $($tt)*\n    };\n}\n\nmacro_rules! tuple_impls {\n    ($(\n        $Tuple:tt {\n            $(($idx:tt) -> $T:ident, $ST:ident, $TT:ident,)+\n        }\n    )+) => {\n        $(\n            fake_variadic!{\n                $Tuple ->\n                impl<$($T),+, __DB> HasSqlType<($($T,)+)> for __DB where\n                    $(__DB: HasSqlType<$T>),+,\n                    __DB: Backend,\n                {\n                    fn metadata(_: &mut __DB::MetadataLookup) -> __DB::TypeMetadata {\n                        unreachable!(\"Tuples should never implement `ToSql` directly\");\n                    }\n                }\n            }\n\n            impl_from_sql_row!(($($T,)+), ($($ST,)+));\n\n\n            fake_variadic! {\n                $Tuple ->\n                #[diagnostic::do_not_recommend]\n                impl<$($T: Expression),+> Expression for ($($T,)+)\n                where ($($T::SqlType, )*): TypedExpressionType\n                {\n                    type SqlType = ($(<$T as Expression>::SqlType,)+);\n                }\n            }\n            fake_variadic! {\n                $Tuple -> impl<$($T: TypedExpressionType,)*> TypedExpressionType for ($($T,)*) {}","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/diesel-rs/diesel/blob/6fa6ed01b24b24248ab2a611698d0a7c6a2e9120/diesel/src/type_impls/tuples.rs#L41-L77","documentation":"Diesel's macro-generated `HasSqlType` implementation for tuples calls `unreachable!` in `metadata()` with this message (comment/branch nominally about tuple `ToSql`). Tuples are supported as row types only via `FromSqlRow`/`Queryable`, not as a directly serializable `ToSql` column type. Hitting this means code attempted to serialize a tuple as a single value.","triggerScenarios":"Using a tuple like `(a, b)` as a bind parameter / `ToSql` value in a query (e.g. `.eq((1,2))`, `.insert((1,2))` into a single column, or passing a tuple where a single-column value is expected); calling `ToSql` methods on a tuple type directly.","commonSituations":"Trying to compare a column against a tuple ('IN' misuse) instead of using `eq_any(vec![...])`; mixing up row tuples with column values in `insert_into(...).values(...)`; generated code/dsl misuse in custom backend code.","solutions":["Use `eq_any` with a Vec for membership tests instead of a tuple equality: `.filter(id.eq_any(vec![1, 2]))`.","Bind each tuple element to its own column instead of the tuple as a whole.","If you need a composite value, define a proper struct with diesel's `Queryable`/`Insertable` derives, or use `(a, b)` row patterns only where diesel supports row comparisons with a matching backend.","Check that you aren't passing a tuple to a single-column insert value slot."],"exampleFix":"// before\nusers.filter((id, name).eq((1, \"a\".to_string()))) // tuple used as single ToSql value\n// after\nusers.filter(id.eq(1).and(name.eq(\"a\")))","handlingStrategy":"type-guard","validationCode":"// compile-time: don't pass tuples as single-column values\n// bad: users.filter(id.eq((1, 2)))\n// good: users.filter(id.eq_any(vec![1, 2]))","typeGuard":"// only tuples of ToSql fields used via row traits are valid; never call ToSql on a tuple\nfn assert_single_column<V: diesel::serialize::ToSql<ST, DB>>(_: &V) {}\n// example: assert_single_column(&user_id); // compiles; assert_single_column(&(1, 2)); // does not","tryCatchPattern":null,"preventionTips":["Use eq_any / per-column filters instead of tuple equality against one column.","Only use tuple row patterns where diesel's DSL supports them for your backend.","Model composite values with derives (Queryable/Insertable), not raw tuples as column values."],"tags":["types","to-sql","tuples","compile-time-panic"],"backgroundTag":"unsupported-operation","analyzedSha":"6fa6ed01b24b24248ab2a611698d0a7c6a2e9120","analyzedAt":"2026-09-07T01:50:13.074Z","contentChangedAt":"2026-09-07T01:50:13.074Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}