diff --git a/AGENT_CHAT.md b/AGENT_CHAT.md index b3986c62..53fcd0c0 100644 --- a/AGENT_CHAT.md +++ b/AGENT_CHAT.md @@ -1,5 +1,9 @@ # RedlineDB Agent Chat +## 2026-09-25T19:10Z perf/one-pass-scan + +Claim: canonical checkout `/home/ubuntu/redlineDB`, branch `perf/one-pass-scan` from `origin/main` `1e21f23caa5842ca2469ec444a6edc4ac4bf36fa`. An unordered table scan keeps the row from the visibility load instead of decoding it again. Index probes stay rowid lookups. Join order and `LIMIT 1` stay as locked. No speed ratio. No worktree. + ## 2026-09-25T18:40Z fix/kernel-p0-gates Claim: canonical checkout `/home/ubuntu/redlineDB`, branch `fix/kernel-p0-gates` from `origin/main` `76ba2a52c469c8917929418ff1f4fe8f5b6623cf`. Clock eviction can decay a hot clean frame, a free row lock is not granted ahead of a queued waiter, a WAL segment that fills exactly does not grow past its limit, and a morsel arena offset that does not fit in `u32` aborts instead of truncating. No speed claim. No worktree. diff --git a/crates/sql/src/exec/morsel/route.rs b/crates/sql/src/exec/morsel/route.rs index 6a58f95b..b3e463d3 100644 --- a/crates/sql/src/exec/morsel/route.rs +++ b/crates/sql/src/exec/morsel/route.rs @@ -629,14 +629,10 @@ pub(crate) fn execute_routed_scan( } }; - let rowids = super::super::collect_table_rowids(engine, tx, table)?; - let mut out: Vec> = Vec::with_capacity(rowids.len()); - - for rowid in rowids { - let Some(fresh) = super::super::load_table_row_by_rowid(engine, tx, table, rowid)? else { - continue; - }; + let rows = super::super::collect_table_rows(engine, tx, table)?; + let mut out: Vec> = Vec::with_capacity(rows.len()); + for fresh in rows { // W4-A3/A5: predicate evaluation before projection. SQL's three- // valued comparison: NULL anything = NULL, treated as // "not matching" (same as the tuple path's filter). For a diff --git a/crates/sql/src/exec/select_top.rs b/crates/sql/src/exec/select_top.rs index 28a838c3..95dc6505 100644 --- a/crates/sql/src/exec/select_top.rs +++ b/crates/sql/src/exec/select_top.rs @@ -3,6 +3,31 @@ use super::select_parallel::{ }; use super::*; +/// One visibility load, then project. The unordered heap scan used to +/// decode each row to drop invisible versions and decode the survivors +/// again in the table cursor. +fn visible_table_scan( + conn: &Connection, + tx: &mut Txn, + table: &Arc, + plan: &crate::statement::SelectPlan, + bindings: &[Option], +) -> Result { + let loaded = collect_table_rows(conn.engine(), tx, table)?; + let mut projected = Vec::with_capacity(loaded.len()); + for row in loaded { + let row = SqlRow::Table(row); + if !selection_passes(&plan.selection, &row, bindings)? { + continue; + } + projected.push(project_row(&plan.projection, &row, bindings)?); + } + Ok(SelectRuntimeSource::StaticRows { + rows: Arc::from(projected), + cursor: 0, + }) +} + pub(super) fn begin_select_tx(conn: &Connection) -> Result<(SelectRuntimeTx, bool)> { if let Some(tx_ptr) = current_tx() { return Ok((SelectRuntimeTx::Borrowed(tx_ptr), false)); @@ -400,8 +425,12 @@ fn build_select_runtime( } else { selection_rowid_eq(table, &plan.selection, bindings)? }; - let rowids = if let Some(rowid) = rowid_candidate { - vec![rowid] + if let Some(rowid) = rowid_candidate { + SelectRuntimeSource::Table { + table: Arc::clone(table), + rowids: vec![rowid], + cursor: 0, + } } else if let Some(matched) = index_access::try_match_index_access_hinted( conn.engine(), table, @@ -419,24 +448,24 @@ fn build_select_runtime( // executor can satisfy them, but a lagging // schema snapshot can still exist. if index_access::open_handle(conn.engine(), &matched.index).is_some() { - index_access::execute_index_probe( + let rowids = index_access::execute_index_probe( conn.engine(), tx, table, &matched.index, &matched.probe, - )? + )?; + SelectRuntimeSource::Table { + table: Arc::clone(table), + rowids, + cursor: 0, + } } else { - collect_table_rowids(conn.engine(), tx, table)? + visible_table_scan(conn, tx, table, plan, bindings)? } } else { let tx = tx.as_mut().expect("tx present"); - collect_table_rowids(conn.engine(), tx, table)? - }; - SelectRuntimeSource::Table { - table: Arc::clone(table), - rowids, - cursor: 0, + visible_table_scan(conn, tx, table, plan, bindings)? } } else if let Some(rowids) = try_ordered_index_limit_path( conn,