join: add --ignore-empty to skip pairing on empty-string join keys (#1194) (#2210)

By default, records with an empty-string value in a join field are
paired just like any other value, so two records both missing an ID
get matched with each other -- rarely the intended behavior.
--ignore-empty treats an empty-string join-field value as if the
field were absent, on both the left and right files, so such records
fall through to unpaired handling (--np/--ul/--ur) instead of
cross-joining on the empty string.

Wires the check through both the default half-streaming join and the
-s/--sorted-input doubly-streaming join, which track left-file
buckets independently and needed the same empty-aware key-presence
check in JoinBucketKeeper.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
John Kerl 2026-07-15 16:42:39 -04:00 committed by GitHub
parent fb3d87a3d5
commit 1a20b32bb5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 267 additions and 14 deletions

View file

@ -1538,6 +1538,13 @@
--ul Emit unpaired records from the left file.
--ur Emit unpaired records from the right
file(s).
--ignore-empty Treat records with empty-string values in
any join-field as if that join-field were
absent, on both the left and right files.
Such records are never paired -- not even
with one another -- and are treated as
unpaired, subject to --np/--ul/--ur as
usual.
-s|--sorted-input Require sorted input: records must be
sorted lexically by their join-field names,
else not all records will be paired. The

View file

@ -1912,6 +1912,13 @@ Options:
--ul Emit unpaired records from the left file.
--ur Emit unpaired records from the right
file(s).
--ignore-empty Treat records with empty-string values in
any join-field as if that join-field were
absent, on both the left and right files.
Such records are never paired -- not even
with one another -- and are treated as
unpaired, subject to --np/--ul/--ur as
usual.
-s|--sorted-input Require sorted input: records must be
sorted lexically by their join-field names,
else not all records will be paired. The