Skip to content

Join implementation

Alexey Ozeritskiy edited this page Oct 14, 2026 · 1 revision

Join implementation

Implementation reference checked against f5e786f. Fundamental explanations remain in docs/arch.

Generated entrypoints

compiler.cpp composes a join program with jt_dispatch and jt_materialize. Init, process, stream probe, semi/anti and outer finalization, and destruction are operations dispatched through it; they are not a public table of independently bound function pointers. CompileJoinHash exports jt_hash_left and jt_hash_right for repartitioning.

gen.cpp and join_gen.cpp provide key/residual/materialization code; generic kernels are under qdb/kernel/join. TInnerJoinProcessor and TCrossJoinProcessor live in join_exec.cpp.

Row references and pair buffers

Retained rows use packed (batch_index << 32) | row_index identifiers. kNullRowId = -1 represents the absent side. A transient stream batch uses a batch-index sentinel only while its residual and output are being processed.

PairBuffer.Data[2*i] and [2*i+1] hold the left/right row identifiers. Kernel code owns capacity growth; the processor drains pending pairs before reusing it. Row-store bases are refreshed on calls because growing their backing vectors can invalidate a previous base pointer.

The shared hash-table ABI uses dense buffers for bucket row count, capacity, and row-id storage. This is distinct from aggregation's typed reducer states. String keys own their persistent bytes through the common arena lifecycle.

Scheduling and support

EJoinStreamMode records symmetric, left-against-right, or right-against-left streaming. Estimates can select build-first inner execution at the current 10:1 asymmetry threshold. Outer joins retain both sides and finalize unmatched rows; residual rejection does not mark a row matched.

Runtime kernels accept Inner, Left, Right, Full, LeftSemi, and LeftAnti. RightSemi/RightAnti enum values are not directly accepted by CompileJoin. String and nullable keys and outer residuals are supported; the old exclusions are obsolete. Join lifecycle and dispatch signatures from earlier revisions are retained only as historical notes in the migration archive.

Clone this wiki locally