mirror of
https://github.com/postgres/postgres.git
synced 2025-10-24 01:29:19 +03:00
Support RIGHT and FULL OUTER JOIN in hash joins.
This is advantageous first because it allows us to hash the smaller table regardless of the outer-join type, and second because hash join can be more flexible than merge join in dealing with arbitrary join quals in a FULL join. For merge join all the join quals have to be mergejoinable, but hash join will work so long as there's at least one hashjoinable qual --- the others can be any condition. (This is true essentially because we don't keep per-inner-tuple match flags in merge join, while hash join can do so.) To do this, we need a has-it-been-matched flag for each tuple in the hashtable, not just one for the current outer tuple. The key idea that makes this practical is that we can store the match flag in the tuple's infomask, since there are lots of bits there that are of no interest for a MinimalTuple. So we aren't increasing the size of the hashtable at all for the feature. To write this without turning the hash code into even more of a pile of spaghetti than it already was, I rewrote ExecHashJoin in a state-machine style, similar to ExecMergeJoin. Other than that decision, it was pretty straightforward.
This commit is contained in:
@@ -195,6 +195,14 @@ typedef HeapTupleHeaderData *HeapTupleHeader;
|
||||
|
||||
#define HEAP2_XACT_MASK 0xC000 /* visibility-related bits */
|
||||
|
||||
/*
|
||||
* HEAP_TUPLE_HAS_MATCH is a temporary flag used during hash joins. It is
|
||||
* only used in tuples that are in the hash table, and those don't need
|
||||
* any visibility information, so we can overlay it on a visibility flag
|
||||
* instead of using up a dedicated bit.
|
||||
*/
|
||||
#define HEAP_TUPLE_HAS_MATCH HEAP_ONLY_TUPLE /* tuple has a join match */
|
||||
|
||||
/*
|
||||
* HeapTupleHeader accessor macros
|
||||
*
|
||||
@@ -343,6 +351,21 @@ do { \
|
||||
(tup)->t_infomask2 &= ~HEAP_ONLY_TUPLE \
|
||||
)
|
||||
|
||||
#define HeapTupleHeaderHasMatch(tup) \
|
||||
( \
|
||||
(tup)->t_infomask2 & HEAP_TUPLE_HAS_MATCH \
|
||||
)
|
||||
|
||||
#define HeapTupleHeaderSetMatch(tup) \
|
||||
( \
|
||||
(tup)->t_infomask2 |= HEAP_TUPLE_HAS_MATCH \
|
||||
)
|
||||
|
||||
#define HeapTupleHeaderClearMatch(tup) \
|
||||
( \
|
||||
(tup)->t_infomask2 &= ~HEAP_TUPLE_HAS_MATCH \
|
||||
)
|
||||
|
||||
#define HeapTupleHeaderGetNatts(tup) \
|
||||
((tup)->t_infomask2 & HEAP_NATTS_MASK)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user