Skip to content

Fix off-by-one in dogsdogsdogs lookup_map (index(1) -> index(0))#765

Open
oflatt wants to merge 1 commit into
TimelyDataflow:masterfrom
oflatt:fix-lookup-map-index-oob
Open

Fix off-by-one in dogsdogsdogs lookup_map (index(1) -> index(0))#765
oflatt wants to merge 1 commit into
TimelyDataflow:masterfrom
oflatt:fix-lookup-map-index-oob

Conversation

@oflatt

@oflatt oflatt commented Jun 20, 2026

Copy link
Copy Markdown

dogsdogsdogs::operators::lookup_map stages the probe key into a capacity-1 KeyContainer, pushes one element (valid index 0), but reads it back at index(1) — out of bounds — for both the seek_key and get_key comparisons. This panics on every probe, so any lookup_map-based operator (e.g. the worst-case-optimal delta-query path extendpropose/count/validatelookup_map) is unusable.

Fix: read the staged key at index(0).

Test: adds dogsdogsdogs/tests/lookup_map_regression.rs, which drives a triangle worst-case-optimal join over a small in-memory triangle — it panics before the fix and finds (0, 1, 2) after.

Found while building a worst-case-optimal join backend on differential dataflow for an e-graph / Datalog engine.

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings June 20, 2026 18:06

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a panic in dogsdogsdogs::operators::lookup_map caused by reading from a capacity-1 KeyContainer at index(1) instead of index(0), and adds a regression test that exercises the WCOJ extend -> propose/count/validate -> lookup_map path on a simple triangle input.

Changes:

  • Fix out-of-bounds KeyContainer access in lookup_map by switching index(1) to index(0) for both seek_key and get_key comparisons.
  • Add a regression test that runs a triangle WCOJ dataflow and asserts the expected (0, 1, 2) result.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
dogsdogsdogs/src/operators/lookup_map.rs Fixes the off-by-one key staging bug that causes lookup_map to panic on probes.
dogsdogsdogs/tests/lookup_map_regression.rs Adds an integration regression test that would panic pre-fix and should find the triangle post-fix.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +70 to +75
.inspect_batch(move |_t, xs| {
let mut v = found_outer.lock().unwrap();
for (data, _t, _r) in xs {
v.push(*data);
}
})
Comment on lines +3 to +5
//! `lookup_map` stages the probe key into a capacity-1 `KeyContainer`, pushes one
//! element (valid index 0), and (before the fix) read it back at index 1 — out of
//! bounds, panicking on *every* probe. This test drives a triangle worst-case-optimal
@oflatt oflatt force-pushed the fix-lookup-map-index-oob branch from a296584 to 45739ae Compare June 20, 2026 18:14
@oflatt

oflatt commented Jun 20, 2026

Copy link
Copy Markdown
Author

For context, I'm working on an experimental version of egglog that uses flowlog + dogsdogsdogs as the backing database engine

@antiguru

Copy link
Copy Markdown
Member

I can confirm that I found exactly the same problem, and my agent fixed it the same way. Only that I didn't put up a PR :) Thank you!

@frankmcsherry

Copy link
Copy Markdown
Member

Yup; looks very plausible. I'm up for merging, but I'm going to need to rethink the testing posture. Much of this is not actively tested / maintained (vs the half_join cohort, which is). Seems like a good reason to get ducks back in a row. Is it right that the test is mostly just the example, but driven with actual data?

key_con is cleared and has exactly one element pushed (push_own), so the only valid index is 0; index(1) reads past the end and panics on every lookup ("index out of bounds: the len is 1 but the index is 1"). Regressed in TimelyDataflow#628 (removing BatchContainer::borrow_as forced a staged KeyContainer that mis-indexed).

Adds a regression test (dogsdogsdogs/tests/lookup_map_regression.rs): a triangle WCOJ over a one-triangle in-memory graph driving lookup_map via extend; it panics on the unfixed code and passes after the fix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@oflatt oflatt force-pushed the fix-lookup-map-index-oob branch from 45739ae to f8d47af Compare June 20, 2026 20:36
@oflatt

oflatt commented Jun 20, 2026

Copy link
Copy Markdown
Author

Yeah the test is a small example- I ran into a bug with a much larger egglog test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants