From 009c3f22ea8227a301b1417e1f4bd197ae2084ca Mon Sep 17 00:00:00 2001 From: lucas11776 Date: Tue, 21 Apr 2026 12:12:09 +0200 Subject: [PATCH 1/6] Testing: merge arguments --- sqlx-core/src/any/arguments.rs | 11 +++++++ sqlx-core/src/arguments.rs | 6 ++++ sqlx-mysql/src/arguments.rs | 11 +++++++ sqlx-postgres/src/arguments.rs | 55 ++++++++++++++++++++++++++++++++++ sqlx-sqlite/src/arguments.rs | 11 +++++++ 5 files changed, 94 insertions(+) diff --git a/sqlx-core/src/any/arguments.rs b/sqlx-core/src/any/arguments.rs index 59d6f4d6e0..1107ec48ac 100644 --- a/sqlx-core/src/any/arguments.rs +++ b/sqlx-core/src/any/arguments.rs @@ -10,6 +10,7 @@ use std::sync::Arc; pub struct AnyArguments { #[doc(hidden)] pub values: AnyArgumentBuffer, + // pub position_values: } impl Arguments for AnyArguments { @@ -30,6 +31,16 @@ impl Arguments for AnyArguments { fn len(&self) -> usize { self.values.0.len() } + + fn merge(&mut self, arguments: Self) { + todo!() + } + + fn position<'t, T>(&mut self, position: u32, value: T) -> Result<(), BoxDynError> + where + T: Encode<'t, Self::Database> + Type { + todo!() + } } #[derive(Default)] diff --git a/sqlx-core/src/arguments.rs b/sqlx-core/src/arguments.rs index 7b9da60b9c..300c12e631 100644 --- a/sqlx-core/src/arguments.rs +++ b/sqlx-core/src/arguments.rs @@ -27,6 +27,12 @@ pub trait Arguments: Send + Sized + Default { fn format_placeholder(&self, writer: &mut W) -> fmt::Result { writer.write_str("?") } + + fn merge(&mut self, arguments: Self); + + fn position<'t, T>(&mut self, position: u32, value: T) -> Result<(), BoxDynError> + where + T: Encode<'t, Self::Database> + Type; } pub trait IntoArguments: Sized + Send { diff --git a/sqlx-mysql/src/arguments.rs b/sqlx-mysql/src/arguments.rs index 306431039d..4cc08717ca 100644 --- a/sqlx-mysql/src/arguments.rs +++ b/sqlx-mysql/src/arguments.rs @@ -55,6 +55,17 @@ impl Arguments for MySqlArguments { fn len(&self) -> usize { self.types.len() } + + fn merge(&mut self, arguments: Self) { + panic!("function not implemented"); + } + + fn position<'t, T>(&mut self, position: u32, value: T) -> Result<(), BoxDynError> + where + T: Encode<'t, Self::Database> + Type + { + panic!("function not implemented"); + } } #[derive(Debug, Default, Clone)] diff --git a/sqlx-postgres/src/arguments.rs b/sqlx-postgres/src/arguments.rs index c0db982c7d..10af4c5f91 100644 --- a/sqlx-postgres/src/arguments.rs +++ b/sqlx-postgres/src/arguments.rs @@ -161,8 +161,63 @@ impl Arguments for PgArguments { fn len(&self) -> usize { self.buffer.count } + + fn merge(&mut self, mut arguments: Self) { + // Merge `Arguments.types` + { + self.types.append(&mut arguments.types); + } + // Merge `Arguments.Buffer` + { + // Merge `buffer` + self.buffer.buffer.append(&mut arguments.buffer.buffer); + + // Merge `patches` + self.buffer.patches.append(&mut arguments.buffer.patches); + + // Merge `type_holes` + self.buffer.type_holes.append(&mut arguments.buffer.type_holes); + + // Increment number of arguments + self.buffer.count += arguments.buffer.count; + } + + drop(arguments); + } + + fn position<'t, T>(&mut self, position: u32, value: T) -> Result<(), BoxDynError> + where + T: Encode<'t, Self::Database> + Type + { + todo!() + } } + +// #[derive(Default, Debug, Clone)] +// pub struct PgArgumentBuffer { +// buffer: Vec, + +// // Number of arguments +// count: usize, + +// // Whenever an `Encode` impl needs to defer some work until after we resolve parameter types +// // it can use `patch`. +// // +// // This currently is only setup to be useful if there is a *fixed-size* slot that needs to be +// // tweaked from the input type. However, that's the only use case we currently have. +// patches: Vec, + +// // Whenever an `Encode` impl encounters a `PgTypeInfo` object that does not have an OID +// // It pushes a "hole" that must be patched later. +// // +// // The hole is a `usize` offset into the buffer with the type name that should be resolved +// // This is done for Records and Arrays as the OID is needed well before we are in an async +// // function and can just ask postgres. +// // +// type_holes: Vec<(usize, HoleKind)>, // Vec<{ offset, type_name }> +// } + impl PgArgumentBuffer { pub(crate) fn encode<'q, T>(&mut self, value: T) -> Result<(), BoxDynError> where diff --git a/sqlx-sqlite/src/arguments.rs b/sqlx-sqlite/src/arguments.rs index 4fd7da5067..0613192ffa 100644 --- a/sqlx-sqlite/src/arguments.rs +++ b/sqlx-sqlite/src/arguments.rs @@ -66,6 +66,17 @@ impl Arguments for SqliteArguments { fn len(&self) -> usize { self.values.0.len() } + + fn merge(&mut self, arguments: Self) { + panic!("function not implemented"); + } + + fn position<'t, T>(&mut self, position: u32, value: T) -> Result<(), BoxDynError> + where + T: Encode<'t, Self::Database> + sqlx_core::types::Type + { + panic!("function not implemented"); + } } impl SqliteArguments { From 84c8ae396df286d16dc07242af84621c6caea87b Mon Sep 17 00:00:00 2001 From: lucas11776 Date: Tue, 21 Apr 2026 14:39:28 +0200 Subject: [PATCH 2/6] Updated: . --- sqlx-postgres/src/arguments.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sqlx-postgres/src/arguments.rs b/sqlx-postgres/src/arguments.rs index 10af4c5f91..80c4447500 100644 --- a/sqlx-postgres/src/arguments.rs +++ b/sqlx-postgres/src/arguments.rs @@ -182,7 +182,7 @@ impl Arguments for PgArguments { self.buffer.count += arguments.buffer.count; } - drop(arguments); + // drop(arguments); } fn position<'t, T>(&mut self, position: u32, value: T) -> Result<(), BoxDynError> From 877d2970c1948eca5e8fc1c7d55bfa66a6ef0866 Mon Sep 17 00:00:00 2001 From: lucas11776 Date: Tue, 21 Apr 2026 17:06:27 +0200 Subject: [PATCH 3/6] Added: Postgres merge arguments --- sqlx-core/src/any/arguments.rs | 6 ---- sqlx-core/src/arguments.rs | 4 --- sqlx-mysql/src/arguments.rs | 7 ---- sqlx-postgres/src/arguments.rs | 64 ++++++++-------------------------- sqlx-sqlite/src/arguments.rs | 7 ---- 5 files changed, 14 insertions(+), 74 deletions(-) diff --git a/sqlx-core/src/any/arguments.rs b/sqlx-core/src/any/arguments.rs index 1107ec48ac..4d62ef0e3e 100644 --- a/sqlx-core/src/any/arguments.rs +++ b/sqlx-core/src/any/arguments.rs @@ -35,12 +35,6 @@ impl Arguments for AnyArguments { fn merge(&mut self, arguments: Self) { todo!() } - - fn position<'t, T>(&mut self, position: u32, value: T) -> Result<(), BoxDynError> - where - T: Encode<'t, Self::Database> + Type { - todo!() - } } #[derive(Default)] diff --git a/sqlx-core/src/arguments.rs b/sqlx-core/src/arguments.rs index 300c12e631..a74219bed1 100644 --- a/sqlx-core/src/arguments.rs +++ b/sqlx-core/src/arguments.rs @@ -29,10 +29,6 @@ pub trait Arguments: Send + Sized + Default { } fn merge(&mut self, arguments: Self); - - fn position<'t, T>(&mut self, position: u32, value: T) -> Result<(), BoxDynError> - where - T: Encode<'t, Self::Database> + Type; } pub trait IntoArguments: Sized + Send { diff --git a/sqlx-mysql/src/arguments.rs b/sqlx-mysql/src/arguments.rs index 4cc08717ca..233523d1d3 100644 --- a/sqlx-mysql/src/arguments.rs +++ b/sqlx-mysql/src/arguments.rs @@ -59,13 +59,6 @@ impl Arguments for MySqlArguments { fn merge(&mut self, arguments: Self) { panic!("function not implemented"); } - - fn position<'t, T>(&mut self, position: u32, value: T) -> Result<(), BoxDynError> - where - T: Encode<'t, Self::Database> + Type - { - panic!("function not implemented"); - } } #[derive(Debug, Default, Clone)] diff --git a/sqlx-postgres/src/arguments.rs b/sqlx-postgres/src/arguments.rs index 80c4447500..1fca1dfde3 100644 --- a/sqlx-postgres/src/arguments.rs +++ b/sqlx-postgres/src/arguments.rs @@ -162,62 +162,26 @@ impl Arguments for PgArguments { self.buffer.count } - fn merge(&mut self, mut arguments: Self) { - // Merge `Arguments.types` - { - self.types.append(&mut arguments.types); + fn merge(&mut self, arguments: Self) { + let buf_offset = self.buffer.len(); + let count_offset = self.buffer.count; + + self.types.extend(arguments.types); + self.buffer.count += arguments.buffer.count; + self.buffer.buffer.extend(arguments.buffer.buffer); + + for mut patch in arguments.buffer.patches { + patch.buf_offset += buf_offset; + patch.arg_index += count_offset; + self.buffer.patches.push(patch); } - // Merge `Arguments.Buffer` - { - // Merge `buffer` - self.buffer.buffer.append(&mut arguments.buffer.buffer); - // Merge `patches` - self.buffer.patches.append(&mut arguments.buffer.patches); - - // Merge `type_holes` - self.buffer.type_holes.append(&mut arguments.buffer.type_holes); - - // Increment number of arguments - self.buffer.count += arguments.buffer.count; + for (offset, kind) in arguments.buffer.type_holes { + self.buffer.type_holes.push((offset + buf_offset, kind)); } - - // drop(arguments); - } - - fn position<'t, T>(&mut self, position: u32, value: T) -> Result<(), BoxDynError> - where - T: Encode<'t, Self::Database> + Type - { - todo!() } } - -// #[derive(Default, Debug, Clone)] -// pub struct PgArgumentBuffer { -// buffer: Vec, - -// // Number of arguments -// count: usize, - -// // Whenever an `Encode` impl needs to defer some work until after we resolve parameter types -// // it can use `patch`. -// // -// // This currently is only setup to be useful if there is a *fixed-size* slot that needs to be -// // tweaked from the input type. However, that's the only use case we currently have. -// patches: Vec, - -// // Whenever an `Encode` impl encounters a `PgTypeInfo` object that does not have an OID -// // It pushes a "hole" that must be patched later. -// // -// // The hole is a `usize` offset into the buffer with the type name that should be resolved -// // This is done for Records and Arrays as the OID is needed well before we are in an async -// // function and can just ask postgres. -// // -// type_holes: Vec<(usize, HoleKind)>, // Vec<{ offset, type_name }> -// } - impl PgArgumentBuffer { pub(crate) fn encode<'q, T>(&mut self, value: T) -> Result<(), BoxDynError> where diff --git a/sqlx-sqlite/src/arguments.rs b/sqlx-sqlite/src/arguments.rs index 0613192ffa..7c5679a797 100644 --- a/sqlx-sqlite/src/arguments.rs +++ b/sqlx-sqlite/src/arguments.rs @@ -70,13 +70,6 @@ impl Arguments for SqliteArguments { fn merge(&mut self, arguments: Self) { panic!("function not implemented"); } - - fn position<'t, T>(&mut self, position: u32, value: T) -> Result<(), BoxDynError> - where - T: Encode<'t, Self::Database> + sqlx_core::types::Type - { - panic!("function not implemented"); - } } impl SqliteArguments { From 4c2c262820579c34ab4da7e3078b51bb5caba54a Mon Sep 17 00:00:00 2001 From: lucas11776 Date: Wed, 22 Apr 2026 09:42:17 +0200 Subject: [PATCH 4/6] Added: sqlx-mysql and sqlx-sqlite merge arguments feature. --- sqlx-mysql/src/arguments.rs | 11 ++++++++++- sqlx-sqlite/src/arguments.rs | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/sqlx-mysql/src/arguments.rs b/sqlx-mysql/src/arguments.rs index 233523d1d3..6af0ba1909 100644 --- a/sqlx-mysql/src/arguments.rs +++ b/sqlx-mysql/src/arguments.rs @@ -57,7 +57,16 @@ impl Arguments for MySqlArguments { } fn merge(&mut self, arguments: Self) { - panic!("function not implemented"); + self.values.extend(arguments.values); + self.types.extend(arguments.types); + + for i in 0..arguments.null_bitmap.length { + let byte_index = i / 8; + let bit_offset = i % 8; + let is_null = (arguments.null_bitmap.bytes[byte_index] & (1 << bit_offset)) != 0; + + self.null_bitmap.push(if is_null { IsNull::Yes } else { IsNull::No }); + } } } diff --git a/sqlx-sqlite/src/arguments.rs b/sqlx-sqlite/src/arguments.rs index 7c5679a797..9ec4501882 100644 --- a/sqlx-sqlite/src/arguments.rs +++ b/sqlx-sqlite/src/arguments.rs @@ -68,7 +68,7 @@ impl Arguments for SqliteArguments { } fn merge(&mut self, arguments: Self) { - panic!("function not implemented"); + self.values.0.extend(arguments.values.0); } } From bcd21a677499d1d83d35349ad9af1d079dda6cd0 Mon Sep 17 00:00:00 2001 From: lucas11776 Date: Wed, 22 Apr 2026 09:51:56 +0200 Subject: [PATCH 5/6] Fixed: lint errors --- sqlx-core/src/any/arguments.rs | 3 +-- sqlx-mysql/src/arguments.rs | 5 +++-- sqlx-postgres/src/arguments.rs | 2 +- sqlx-sqlite/src/arguments.rs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sqlx-core/src/any/arguments.rs b/sqlx-core/src/any/arguments.rs index 4d62ef0e3e..b33629241b 100644 --- a/sqlx-core/src/any/arguments.rs +++ b/sqlx-core/src/any/arguments.rs @@ -10,7 +10,6 @@ use std::sync::Arc; pub struct AnyArguments { #[doc(hidden)] pub values: AnyArgumentBuffer, - // pub position_values: } impl Arguments for AnyArguments { @@ -31,7 +30,7 @@ impl Arguments for AnyArguments { fn len(&self) -> usize { self.values.0.len() } - + fn merge(&mut self, arguments: Self) { todo!() } diff --git a/sqlx-mysql/src/arguments.rs b/sqlx-mysql/src/arguments.rs index 6af0ba1909..10b3dc3fd5 100644 --- a/sqlx-mysql/src/arguments.rs +++ b/sqlx-mysql/src/arguments.rs @@ -55,7 +55,7 @@ impl Arguments for MySqlArguments { fn len(&self) -> usize { self.types.len() } - + fn merge(&mut self, arguments: Self) { self.values.extend(arguments.values); self.types.extend(arguments.types); @@ -65,7 +65,8 @@ impl Arguments for MySqlArguments { let bit_offset = i % 8; let is_null = (arguments.null_bitmap.bytes[byte_index] & (1 << bit_offset)) != 0; - self.null_bitmap.push(if is_null { IsNull::Yes } else { IsNull::No }); + self.null_bitmap + .push(if is_null { IsNull::Yes } else { IsNull::No }); } } } diff --git a/sqlx-postgres/src/arguments.rs b/sqlx-postgres/src/arguments.rs index 1fca1dfde3..51210bde69 100644 --- a/sqlx-postgres/src/arguments.rs +++ b/sqlx-postgres/src/arguments.rs @@ -161,7 +161,7 @@ impl Arguments for PgArguments { fn len(&self) -> usize { self.buffer.count } - + fn merge(&mut self, arguments: Self) { let buf_offset = self.buffer.len(); let count_offset = self.buffer.count; diff --git a/sqlx-sqlite/src/arguments.rs b/sqlx-sqlite/src/arguments.rs index 9ec4501882..7a85449b1c 100644 --- a/sqlx-sqlite/src/arguments.rs +++ b/sqlx-sqlite/src/arguments.rs @@ -66,7 +66,7 @@ impl Arguments for SqliteArguments { fn len(&self) -> usize { self.values.0.len() } - + fn merge(&mut self, arguments: Self) { self.values.0.extend(arguments.values.0); } From b6672a1faae12a1f3e39c3f3ac0617ef6ce7f36d Mon Sep 17 00:00:00 2001 From: lucas11776 Date: Wed, 22 Apr 2026 09:57:33 +0200 Subject: [PATCH 6/6] Fixed: lint errors --- sqlx-core/src/any/arguments.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sqlx-core/src/any/arguments.rs b/sqlx-core/src/any/arguments.rs index b33629241b..8f44f54bdb 100644 --- a/sqlx-core/src/any/arguments.rs +++ b/sqlx-core/src/any/arguments.rs @@ -32,7 +32,7 @@ impl Arguments for AnyArguments { } fn merge(&mut self, arguments: Self) { - todo!() + self.values.0.extend(arguments.values.0); } }