mirror of
https://github.com/postgres/postgres.git
synced 2025-06-30 21:42:05 +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:
@ -1468,6 +1468,10 @@ typedef struct MergeJoinState
|
||||
/* ----------------
|
||||
* HashJoinState information
|
||||
*
|
||||
* hashclauses original form of the hashjoin condition
|
||||
* hj_OuterHashKeys the outer hash keys in the hashjoin condition
|
||||
* hj_InnerHashKeys the inner hash keys in the hashjoin condition
|
||||
* hj_HashOperators the join operators in the hashjoin condition
|
||||
* hj_HashTable hash table for the hashjoin
|
||||
* (NULL if table not built yet)
|
||||
* hj_CurHashValue hash value for current outer tuple
|
||||
@ -1477,14 +1481,12 @@ typedef struct MergeJoinState
|
||||
* tuple, or NULL if starting search
|
||||
* (hj_CurXXX variables are undefined if
|
||||
* OuterTupleSlot is empty!)
|
||||
* hj_OuterHashKeys the outer hash keys in the hashjoin condition
|
||||
* hj_InnerHashKeys the inner hash keys in the hashjoin condition
|
||||
* hj_HashOperators the join operators in the hashjoin condition
|
||||
* hj_OuterTupleSlot tuple slot for outer tuples
|
||||
* hj_HashTupleSlot tuple slot for hashed tuples
|
||||
* hj_NullInnerTupleSlot prepared null tuple for left outer joins
|
||||
* hj_HashTupleSlot tuple slot for inner (hashed) tuples
|
||||
* hj_NullOuterTupleSlot prepared null tuple for right/full outer joins
|
||||
* hj_NullInnerTupleSlot prepared null tuple for left/full outer joins
|
||||
* hj_FirstOuterTupleSlot first tuple retrieved from outer plan
|
||||
* hj_NeedNewOuter true if need new outer tuple on next call
|
||||
* hj_JoinState current state of ExecHashJoin state machine
|
||||
* hj_MatchedOuter true if found a join match for current outer
|
||||
* hj_OuterNotEmpty true if outer relation known not empty
|
||||
* ----------------
|
||||
@ -1498,19 +1500,20 @@ typedef struct HashJoinState
|
||||
{
|
||||
JoinState js; /* its first field is NodeTag */
|
||||
List *hashclauses; /* list of ExprState nodes */
|
||||
List *hj_OuterHashKeys; /* list of ExprState nodes */
|
||||
List *hj_InnerHashKeys; /* list of ExprState nodes */
|
||||
List *hj_HashOperators; /* list of operator OIDs */
|
||||
HashJoinTable hj_HashTable;
|
||||
uint32 hj_CurHashValue;
|
||||
int hj_CurBucketNo;
|
||||
int hj_CurSkewBucketNo;
|
||||
HashJoinTuple hj_CurTuple;
|
||||
List *hj_OuterHashKeys; /* list of ExprState nodes */
|
||||
List *hj_InnerHashKeys; /* list of ExprState nodes */
|
||||
List *hj_HashOperators; /* list of operator OIDs */
|
||||
TupleTableSlot *hj_OuterTupleSlot;
|
||||
TupleTableSlot *hj_HashTupleSlot;
|
||||
TupleTableSlot *hj_NullOuterTupleSlot;
|
||||
TupleTableSlot *hj_NullInnerTupleSlot;
|
||||
TupleTableSlot *hj_FirstOuterTupleSlot;
|
||||
bool hj_NeedNewOuter;
|
||||
int hj_JoinState;
|
||||
bool hj_MatchedOuter;
|
||||
bool hj_OuterNotEmpty;
|
||||
} HashJoinState;
|
||||
|
Reference in New Issue
Block a user