Skip to content

quack: pin SQL NULL operands over existing sql_where (tests + PostgreSQL differential) - #1682

Merged
AdaWorldAPI merged 4 commits into
mainfrom
claude/eager-albattani-iufugq
Oct 21, 2026
Merged

AdaWorldAPI merged 4 commits into
mainfrom
claude/eager-albattani-iufugq

Conversation

@AdaWorldAPI

Copy link
Copy Markdown
Owner

D-QSP-0 slice 2 (G1). Follow-up to #1680. Three files: two new ones and my own board entry.

Contract

SQL NULL is absence of validity, never 0 and never FALSE. A nullable value is a value lane plus a validity plane (1 = present, 0 = NULL).

For a nullable predicate:

  • T = valid ∧ p
  • F = valid ∧ ¬p
  • UNKNOWN = ¬(T ∨ F)

Quack's T is f.sql_where(nullable). Its F is Filter::Not(f).sql_where(nullable).

NULL operand. x = NULL, NULL < c, NULL::boolean and the NULL member of IN all map to Filter::Cmp(N, …). N is a column whose value lane is an alias of an existing lane and whose validity plane is all clear, listed in nullable. Its T and F are empty on every row.

FALSE literal. A Filter::Plane over an all-zero plane that is present, so its F is every row. FALSE and UNKNOWN stay distinct.

Reused, nothing added

  • Filter::{Cmp, Plane, And, Or, Not}, sql_where, lower, lower_fused
  • mask-risc execute_into with Out::Mask
  • mask-risc Xor then Any for every comparison

There is no new Filter variant, evaluator, counting loop or terminal, and src/lib.rs is untouched.

Files

  • crates/lance-graph-quack/tests/sql_null_operand.rs (new, 11 tests, runs in CI)
  • crates/lance-graph-quack/examples/qsp_null_operand_pg_parity.rs (new, PostgreSQL differential, prints SKIP without a server)
  • .claude/board/entries/2026-10-21-d-qsp-0-scalar-aggregates-null.md (my entry, slice 2 section)

Evidence

Committed tests (8 rows, the NULL payload equals the IN value). Both lowerings are checked and must agree. Results:

case result
x = NULL T = F = ∅
NOT (x = NULL) T = F = ∅
x IN (1, NULL) T = the matches, F = ∅
x NOT IN (1, NULL) T = ∅
AND, OR, NOT over TRUE, FALSE, UNKNOWN full truth tables match SQL
FALSE vs UNKNOWN differ on the F plane
every invalid payload and the N lane scrambled no plane changes

PostgreSQL 16.15, 2000 random expressions × 200 rows. The T and F planes equal PostgreSQL on every expression, in both lowerings, and again with every invalid payload re-drawn. The run covered:

  • 165278 UNKNOWN row-verdicts;
  • 1369 expressions with a NULL operand;
  • 250 cases of NOT IN (…, NULL) with an empty T.

Built-in disable arms (each asserted > 0):

  • UNKNOWN read as FALSE differs from PostgreSQL on 1050 expressions;
  • N left out of nullable differs on 1107.

Disable runs:

  • D1, NULL operand mapped to the FALSE plane: 9/11 tests red.
  • D2, N not in nullable: 9/11 red.
  • D3, sql_where skipped: 9/11 red.
  • D4, production disable, reverted after the run (sql_where's leaf arm without its validity gate): 9/11 red. The PostgreSQL example exits 101.

Gates: the quack crate has 137 tests passing, clippy -D warnings is clean, and fmt is clean.

Not in this PR

  • The G1 rows of entries/2026-10-21-pg-classview-polyfill-map.md are still stale. That file belongs to another session; the entry names the rows.
  • Still open: column-versus-column comparisons (G4); COALESCE, NULLIF and nullable arithmetic; the NULL branch of a NOT IN subquery.

Merge is attended: I will not merge this PR.


Generated by Claude Code

…y plane

Corrects the polyfill map's G1 rows and gap item 1, which said a NULL
literal needs a constant-UNKNOWN Filter leaf. It does not: sql_where's
leaf arm already gives a NULL operand T = F = empty. sql_where's doc
comment no longer lists the NULL literal as out of scope. Doc and board
only; no code change. Tests follow in this branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013z2e1YXkm6o6HNrDn5BPWA
…SQL differential)

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

coderabbitai Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 68aeda20-1bec-4cb7-9011-b3e992ae1f1a
  • 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.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 21, 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-21T21:04:01.279808Z 96e8010 PR opened
ℹ️ 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.

@coderabbitai

coderabbitai Bot commented Oct 21, 2026

Copy link
Copy Markdown

Add Carrot credits or activate Agent usage billing to use Autofix

@AdaWorldAPI
AdaWorldAPI merged commit da9b755 into main Oct 21, 2026
18 checks passed
AdaWorldAPI pushed a commit that referenced this pull request Oct 21, 2026
…1680/#1682, boundaries

Only this session's rows and entry: the STATUS_BOARD "D-QSP-0 remainder"
row (In PR -> Shipped, slice 2 added), PR_ARC entries for #1675, #1680 and
#1682 prepended, and the entry now states that Quack has no NULL-literal
Filter variant, that the PostgreSQL examples are lab evidence and not CI,
and #1682's final CI (18/18 green on 96e8010).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013z2e1YXkm6o6HNrDn5BPWA
AdaWorldAPI added a commit that referenced this pull request Oct 21, 2026
board: reconciliation after #1674–#1682 — D-QSP-0 row, D-RFT-1 row, polyfill map G1, PR_ARC
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