Skip to content

quack: intersect ANDed row ranges on one column before lowering (D-TELEPORT-1) - #1487

Merged
AdaWorldAPI merged 1 commit into
mainfrom
ccr-b576712f-pexwof
Oct 11, 2026
Merged

AdaWorldAPI merged 1 commit into
mainfrom
ccr-b576712f-pexwof

Conversation

@AdaWorldAPI

Copy link
Copy Markdown
Owner

What

Adds a small rewrite, fold_ranges, in lance-graph-quack. It runs first thing in lower_with, so lower, lower_fused and lower_group_by all pick it up.

Inside each AND, the direct children Cmp(col, Range { lo, hi }) that share a col are replaced by one range, [max(lo), max(max(lo), min(hi))), placed where the first of them was.

Why

PR #1484's probe measured Range AND Range lowering to three passes (two range writes and an And, ~10 µs on 1M rows). After this rewrite the two ranges are already one before execution: a property of two boundaries.

  • COUNT / ANY: mask-risc answers a single range from hi − lo without visiting any row (Lowering::Range).
  • Other terminals: they still visit every row in the intersected range. The rewrite saves two passes and two slots there, not the rows.

Edges

  • Empty intersections: disjoint ranges become Range { lo: x, hi: x }. This is still a valid range (lo ≤ hi), so mask-risc accepts it.
  • Row order: a Range is row ordinals in the order of the lane it was bound against, and col is the only order identity a Filter carries. So only ranges on the same column merge.
  • Scope: only siblings of one AND merge. A range under an OR or NOT is never merged with one outside it, and nested ANDs are not flattened.
  • Refusals kept: a range with lo > hi is not merged, so mask-risc still refuses it.
  • Refusal that can be lost: a bound past n_rows cannot be seen here, because a filter carries no row count. If it is on the side the intersection drops, the merged range runs. prefix_facet and aperture_facet, which bound ranges against a sealed lane, never emit one. This is written in the function's doc.

Tests (range_fold_tests)

  • An overlapping pair lowers to one op and Lowering::Range, and gives the right count under both lowerings.
  • A disjoint pair lowers to an empty range and counts 0.
  • Different columns, OR and NOT are left alone, and a lone range is unchanged.
  • An inverted range (lo > hi) is not merged.
  • 400 seeded random conjunctions, mixed with a plane and lane compares, match a row-by-row oracle under both lowerings; more than 300 of them exercise the merge.

Disable runs, each red: hook removed; merging across columns; min instead of max for lo; no empty clamp; inverted ranges merged; ranges merged under OR.

Checks

  • lance-graph-quack full suite passes; clippy -D warnings and fmt clean
  • lance-graph-cypher-quack passes
  • CI

Board: new D-TELEPORT-1 row; D-TELEPORT-0 and D-SQLP-2 marked shipped in #1484.

🤖 Generated with Claude Code

https://claude.ai/code/session_015JH7YkXs5us6g3tG8NiFfP


Generated by Claude Code

D-TELEPORT-1. fold_ranges runs at the top of lower_with, so lower,
lower_fused and lower_group_by all see it. Inside each AND, the direct
children Cmp(col, Range{lo, hi}) sharing a col become one range
[max(lo), max(max(lo), min(hi))), kept at the first one's position.

- Empty intersections stay valid empty ranges (lo == hi), never lo > hi.
- Row-order identity: only ranges on the same col merge; col is the only
  order identity a Filter carries.
- Siblings of one AND only; never across OR or NOT; nested ANDs are not
  flattened.
- A range with lo > hi is not merged, so mask-risc still refuses it. A
  bound past n_rows on the side the intersection drops cannot be seen
  here; the producers that bound ranges never emit one. Documented.

Under COUNT/ANY the single range takes mask-risc's closed form (hi - lo,
no row visited). Under other terminals the survivors are still visited,
minus two passes and two slots.

Tests (range_fold_tests): one op and Lowering::Range for an overlapping
pair; an empty range for a disjoint pair; different columns, OR and NOT
left alone; an inverted range not merged; 400 seeded conjunctions with
planes and lane compares equal to a row-by-row oracle under both
lowerings. Disable runs, each red: hook removed; merge across columns;
min instead of max; no empty clamp; inverted merged; OR merged.
quack full suite and lance-graph-cypher-quack green.

Board: D-TELEPORT-1 row; D-TELEPORT-0 and D-SQLP-2 marked shipped (#1484).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015JH7YkXs5us6g3tG8NiFfP
@coderabbitai

coderabbitai Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

Next included review available in 1 minute.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available. Your 63 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: 76a8ef50-a43a-412f-bc44-1fbd5531154b

📥 Commits

Reviewing files that changed from the base of the PR and between 4c3e813 and f17feba.


📒 Files selected for processing (2)
  • .claude/board/STATUS_BOARD.md
  • crates/lance-graph-quack/src/lib.rs

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption.


Comment @coderabbitai help to get the list of available commands.

@AdaWorldAPI
AdaWorldAPI marked this pull request as ready for review October 11, 2026 11:36
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-11T11:38:18.964679Z f17feba Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@AdaWorldAPI
AdaWorldAPI merged commit 31652c5 into main Oct 11, 2026
14 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f17feba68b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

let p = fold_ranges(p);
if let Filter::Cmp(col, Cmp::Range { lo, hi }) = p {
if lo <= hi {
let seen = first.iter().find(|(c, _)| *c == col).map(|&(_, i)| i);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use constant-time range-column lookup

When an AND contains k valid ranges on distinct columns, first grows to k entries and every child scans it linearly, making lower and lower_fused take Θ(k²) time before gate_walk; because Col spans the full u16 range and Filter::and accepts arbitrary iterators, generated wide predicates can trigger billions of comparisons. Indexing by Col with a fixed table or map preserves linear planning time, and a wide distinct-column benchmark should cover this performance-sensitive path.

AGENTS.md reference: AGENTS.md:L24-L27

Useful? React with 👍 / 👎.

AdaWorldAPI pushed a commit that referenced this pull request Oct 11, 2026
64 populations x 1,048,576 addresses in four regimes (sparse, dense,
clustered, 256 archetypes). Compares quack-fused and in-place plane
lowering, single-range extents, per-address u64 signatures and
signature-equivalence classes on COUNT, Any, SUM and Rows; the canonical
expression plus 20 random ones equal the oracle in every arm. Also
measures transpose, class build, 1,000-address updates and spill/reload.

Bit-sliced planes answer in ~0.03-0.05 ms per query regardless of data;
signatures lose by 250-600x; classes win only at a few hundred classes and
cost 30-100x more per update. Board: entries for D-TELEPORT-2 and
D-PHOTO-0, D-TELEPORT-1 marked shipped (#1487).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015JH7YkXs5us6g3tG8NiFfP
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.

2 participants