mirror of
https://github.com/postgres/postgres.git
synced 2025-07-02 09:02:37 +03:00
Arrange for hash join to skip scanning the outer relation if it detects
that the inner one is completely empty. Per recent discussion. Also some cosmetic cleanups in nearby code.
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeHash.c,v 1.86 2004/08/29 04:12:31 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeHash.c,v 1.87 2004/09/22 19:13:49 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -32,8 +32,8 @@
|
||||
/* ----------------------------------------------------------------
|
||||
* ExecHash
|
||||
*
|
||||
* build hash table for hashjoin, all do partitioning if more
|
||||
* than one batches are required.
|
||||
* build hash table for hashjoin, doing partitioning if more
|
||||
* than one batch is required.
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
TupleTableSlot *
|
||||
@ -81,6 +81,7 @@ ExecHash(HashState *node)
|
||||
slot = ExecProcNode(outerNode);
|
||||
if (TupIsNull(slot))
|
||||
break;
|
||||
hashtable->hashNonEmpty = true;
|
||||
econtext->ecxt_innertuple = slot;
|
||||
ExecHashTableInsert(hashtable, econtext, hashkeys);
|
||||
ExecClearTuple(slot);
|
||||
@ -189,7 +190,7 @@ ExecEndHash(HashState *node)
|
||||
/* ----------------------------------------------------------------
|
||||
* ExecHashTableCreate
|
||||
*
|
||||
* create a hashtable in shared memory for hashjoin.
|
||||
* create an empty hashtable data structure for hashjoin.
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
HashJoinTable
|
||||
@ -226,12 +227,13 @@ ExecHashTableCreate(Hash *node, List *hashOperators)
|
||||
* The hashtable control block is just palloc'd from the executor's
|
||||
* per-query memory context.
|
||||
*/
|
||||
hashtable = (HashJoinTable) palloc(sizeof(HashTableData));
|
||||
hashtable = (HashJoinTable) palloc(sizeof(HashJoinTableData));
|
||||
hashtable->nbuckets = nbuckets;
|
||||
hashtable->totalbuckets = totalbuckets;
|
||||
hashtable->buckets = NULL;
|
||||
hashtable->nbatch = nbatch;
|
||||
hashtable->curbatch = 0;
|
||||
hashtable->hashNonEmpty = false;
|
||||
hashtable->innerBatchFile = NULL;
|
||||
hashtable->outerBatchFile = NULL;
|
||||
hashtable->innerBatchSize = NULL;
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeHashjoin.c,v 1.65 2004/09/17 18:28:53 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeHashjoin.c,v 1.66 2004/09/22 19:13:49 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -127,6 +127,17 @@ ExecHashJoin(HashJoinState *node)
|
||||
hashNode->hashtable = hashtable;
|
||||
(void) ExecProcNode((PlanState *) hashNode);
|
||||
|
||||
/*
|
||||
* If the inner relation is completely empty, and we're not doing
|
||||
* an outer join, we can quit without scanning the outer relation.
|
||||
*/
|
||||
if (!hashtable->hashNonEmpty && node->js.jointype != JOIN_LEFT)
|
||||
{
|
||||
ExecHashTableDestroy(hashtable);
|
||||
node->hj_HashTable = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open temp files for outer batches, if needed. Note that file
|
||||
* buffers are palloc'd in regular executor context.
|
||||
@ -138,10 +149,8 @@ ExecHashJoin(HashJoinState *node)
|
||||
}
|
||||
|
||||
/*
|
||||
* Now get an outer tuple and probe into the hash table for matches
|
||||
* run the hash join process
|
||||
*/
|
||||
outerTupleSlot = node->js.ps.ps_OuterTupleSlot;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/*
|
||||
@ -226,7 +235,7 @@ ExecHashJoin(HashJoinState *node)
|
||||
* Only the joinquals determine MatchedOuter status, but all
|
||||
* quals must pass to actually return the tuple.
|
||||
*/
|
||||
if (ExecQual(joinqual, econtext, false))
|
||||
if (joinqual == NIL || ExecQual(joinqual, econtext, false))
|
||||
{
|
||||
node->hj_MatchedOuter = true;
|
||||
|
||||
|
Reference in New Issue
Block a user