diff options
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/access/htup.h | 23 | ||||
-rw-r--r-- | src/include/executor/hashjoin.h | 2 | ||||
-rw-r--r-- | src/include/executor/nodeHash.h | 10 | ||||
-rw-r--r-- | src/include/nodes/execnodes.h | 23 |
4 files changed, 45 insertions, 13 deletions
diff --git a/src/include/access/htup.h b/src/include/access/htup.h index adf1321052c..f540966d684 100644 --- a/src/include/access/htup.h +++ b/src/include/access/htup.h @@ -196,6 +196,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 * * Note: beware of multiple evaluations of "tup" argument. But the Set @@ -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) diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h index 1b93f58af67..c4aa0d37268 100644 --- a/src/include/executor/hashjoin.h +++ b/src/include/executor/hashjoin.h @@ -113,6 +113,8 @@ typedef struct HashJoinTableData struct HashJoinTupleData **buckets; /* buckets array is per-batch storage, as are all the tuples */ + bool keepNulls; /* true to store unmatchable NULL tuples */ + bool skewEnabled; /* are we using skew optimization? */ HashSkewBucket **skewBucket; /* hashtable of skew buckets */ int skewBucketLen; /* size of skewBucket array (a power of 2!) */ diff --git a/src/include/executor/nodeHash.h b/src/include/executor/nodeHash.h index 444a0137a2d..8517d1cf284 100644 --- a/src/include/executor/nodeHash.h +++ b/src/include/executor/nodeHash.h @@ -22,7 +22,8 @@ extern Node *MultiExecHash(HashState *node); extern void ExecEndHash(HashState *node); extern void ExecReScanHash(HashState *node); -extern HashJoinTable ExecHashTableCreate(Hash *node, List *hashOperators); +extern HashJoinTable ExecHashTableCreate(Hash *node, List *hashOperators, + bool keepNulls); extern void ExecHashTableDestroy(HashJoinTable hashtable); extern void ExecHashTableInsert(HashJoinTable hashtable, TupleTableSlot *slot, @@ -37,9 +38,12 @@ extern void ExecHashGetBucketAndBatch(HashJoinTable hashtable, uint32 hashvalue, int *bucketno, int *batchno); -extern HashJoinTuple ExecScanHashBucket(HashJoinState *hjstate, - ExprContext *econtext); +extern bool ExecScanHashBucket(HashJoinState *hjstate, ExprContext *econtext); +extern void ExecPrepHashTableForUnmatched(HashJoinState *hjstate); +extern bool ExecScanHashTableForUnmatched(HashJoinState *hjstate, + ExprContext *econtext); extern void ExecHashTableReset(HashJoinTable hashtable); +extern void ExecHashTableResetMatchFlags(HashJoinTable hashtable); extern void ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew, int *numbuckets, int *numbatches, diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index d669c24b981..6af4bb8d76c 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -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; |