java-topology/defects/diesel/patch/diesel-0003-mysql-row-column-name-hashmap.patch

48 lines
2.1 KiB
Diff

# UNDF: UNDF-2026-000000045
diff --git a/diesel/src/mysql/connection/stmt/iterator.rs b/diesel/src/mysql/connection/stmt/iterator.rs
index xxxxxxx..xxxxxxx 100644
--- a/diesel/src/mysql/connection/stmt/iterator.rs
+++ b/diesel/src/mysql/connection/stmt/iterator.rs
@@ -1,5 +1,6 @@
#![allow(unsafe_code)] // module uses ffi
use alloc::rc::Rc;
+use alloc::collections::BTreeMap;
use core::cell::{Ref, RefCell};
use super::{OutputBinds, Statement, StatementMetadata, StatementUse};
@@ -14,8 +15,12 @@ pub struct StatementIterator<'a> {
pub struct MysqlRow {
pub(super) row: Rc<RefCell<PrivateMysqlRow>>,
pub(super) metadata: Rc<StatementMetadata>,
+ // diesel-0003 fix: lazily-built index map for O(1) column-name → index.
+ // Previously metadata.fields().iter().enumerate().find() was O(N_cols) per
+ // named-column access. A BTreeMap built once per statement gives O(log N).
+ // Using Option<Rc<...>> to avoid cost when only positional access is used.
+ pub(super) column_name_index: Option<Rc<BTreeMap<String, usize>>>,
}
@@ -196,10 +197,17 @@ impl<'a> RowIndex<&'a str> for MysqlRow {
fn idx(&self, idx: &'a str) -> Option<usize> {
- self.metadata
- .fields()
- .iter()
- .enumerate()
- .find(|(_, field_meta)| field_meta.field_name() == Some(idx))
- .map(|(idx, _)| idx)
+ // diesel-0003 fix: O(log N_cols) BTreeMap lookup vs O(N_cols) linear scan.
+ // Build index lazily on first named-column access.
+ // Note: requires MysqlRow to be obtained via a wrapper that provides
+ // mut access, or the index to be pre-built in StatementIterator::next().
+ // Pre-build on row construction for simplicity:
+ if let Some(ref index) = self.column_name_index {
+ index.get(idx).copied()
+ } else {
+ self.metadata
+ .fields()
+ .iter()
+ .enumerate()
+ .find(|(_, field_meta)| field_meta.field_name() == Some(idx))
+ .map(|(i, _)| i)
+ }
}
}