Skip to content

Joins work; it is their speed that is unmeasured (#402 follow-up) - #404

Merged
jdatcmd merged 2 commits into
mainfrom
docs/joins-work-unmeasured
Aug 4, 2026
Merged

Joins work; it is their speed that is unmeasured (#402 follow-up)#404
jdatcmd merged 2 commits into
mainfrom
docs/joins-work-unmeasured

Conversation

@jdatcmd

@jdatcmd jdatcmd commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Follow-up to #402, as I said on the review.

#402 correctly says the join-heavy shapes are absent from the page. It leaves one thing ambiguous: it says nothing about whether joins work, so a reader can come away unsure whether a columnar table joins at all. That is a worse impression than the truth.

Measured on a 200,000-row fixture:

shape result
columnar fact JOIN heap dimension, inner + aggregate identical to heap/heap
LEFT JOIN with nulls identical
heap on the outer side identical
columnar JOIN columnar identical
semijoin (EXISTS) / anti-join (NOT EXISTS) identical
hash / merge / nested loop, each forced all correct, all chosen

Column projection also survives the join (Columnar Projected Columns: 1 of 4), so the columnar side reads only what the join and target list need rather than losing the advantage at the boundary.

So the accurate claim is narrower and stronger than an absence: the speed is unmeasured, the correctness is not in question. #401 still owns the measurement.

Docs only, no em or en dashes.

🤖 Generated with Claude Code

#402 added "What this page does not measure" and it is right that the join-heavy
shapes are absent. It leaves one thing ambiguous: it says nothing about whether
joins work at all, so a reader can come away unsure whether a columnar table
joins. That is a worse impression than the truth.

Measured on a 200,000-row fixture: columnar joined to heap in either direction,
columnar to columnar, inner, left with nulls, semijoin and anti-join, each
returning results identical to the all-heap equivalent, and each of hash, merge
and nested loop correct when forced. Column projection survives the join, so the
columnar side reads only the columns the join and the target list need rather
than losing the advantage at the join boundary.

So the accurate claim is narrower and stronger than an absence: the speed is
unmeasured, the correctness is not in question. #401 still owns the measurement.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@ChronicallyJD ChronicallyJD left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The substance is right and I verified it. One blocker, and it is the docs gate.

You are correcting a real gap in #402. I wrote that the join shapes are absent and said
nothing about whether joins work, so a reader could take the worse reading. That is on me.

Verified rather than taken

Column projection survives the join. Four-column columnar fact, query needing two:

->  Hash Join (actual rows=200000.00 loops=1)
      ->  Custom Scan (ColumnarScan) on f_col f
            Columnar Projected Columns: 2
            Columnar Total Columns: 4

All three strategies, each forced, agree. Same aggregate to the cent:

  hashjoin   plan=Hash Join      20000100000.00
  mergejoin  plan=Merge Join     20000100000.00
  nestloop   plan=Nested Loop    20000100000.00

Merge join is the one I most expected to misbehave, since it needs sorted input on a side
that has no index. It plans and answers correctly.

The blocker: this fails docs_style

$ python3 test/ste_check.py docs/benchmarks.md
  FAIL  docs/benchmarks.md: 1 long, 0 idiom, 0 em/en dash, 0 prose double-hyphen
          49 words: A columnar table joins a heap table in either direction, and a columnar table, under has

49 words against the 25 limit, so the docs_style suite goes red in the matrix. Not a
nitpick, it is a gate failure.

The sentence has a second problem the checker cannot see. "and a columnar table" has no
verb, so it reads as a list item rather than a second join, and "returning" dangles off a
subject that is no longer there. I had to read it three times to be sure what it claimed.

Suggested replacement, which I ran the checker against

Joins themselves work. A columnar table joins a heap table in either direction, and
joins another columnar table. Hash, merge and nested-loop strategies all return the
same rows as the all-heap equivalent. Column projection survives the join, so the
columnar side reads only the columns the join and the target list need. What is
absent is a measurement of how fast that is, not evidence that it works.
$ python3 test/ste_check.py docs/benchmarks.md
  ok    docs/benchmarks.md

Same claims, four sentences instead of one, and the second join gets its verb back.

One addition worth considering

Your evidence covers left, semi and anti joins and both outer sides. The paragraph only
says "in either direction". Since you measured more than that, a clause saying outer and
semi joins behave too would be worth the words, and would answer the next question a
reader has.

Approving on the substance. Fix the sentence and I am happy to see it merge.

docs_style caught my own violation: 49 words against the 25-word limit
test/ste_check.py enforces. The sentence was also badly built, stacking a
coordination and two subordinate clauses on one subject.

Four short sentences instead, same content: joins work in both directions and
columnar to columnar, all three strategies return the all-heap rows, projection
survives the join, and it is the speed that is unmeasured.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jdatcmd
jdatcmd merged commit d2c29fb into main Aug 4, 2026
11 checks passed
@jdatcmd
jdatcmd deleted the docs/joins-work-unmeasured branch August 4, 2026 23:51
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