aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeHashjoin.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-01-28 23:21:26 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-01-28 23:21:26 +0000
commitb39e91501c101d67b92f3e6965da5dc111195f52 (patch)
tree1820d8ba0289c5e32a025b9f62bdd98ca494a972 /src/backend/executor/nodeHashjoin.c
parent28c480e9ae64fc239fa1ebe32a981312e65ae1e7 (diff)
downloadpostgresql-b39e91501c101d67b92f3e6965da5dc111195f52.tar.gz
postgresql-b39e91501c101d67b92f3e6965da5dc111195f52.zip
Improve hash join to discard input tuples immediately if they can't
match because they contain a null join key (and the join operator is known strict). Improves performance significantly when the inner relation contains a lot of nulls, as per bug #2930.
Diffstat (limited to 'src/backend/executor/nodeHashjoin.c')
-rw-r--r--src/backend/executor/nodeHashjoin.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 7f0801c69bd..b03086fb364 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeHashjoin.c,v 1.86 2007/01/05 22:19:28 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeHashjoin.c,v 1.87 2007/01/28 23:21:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -547,9 +547,8 @@ ExecHashJoinOuterGetTuple(PlanState *outerNode,
int curbatch = hashtable->curbatch;
TupleTableSlot *slot;
- if (curbatch == 0)
- { /* if it is the first pass */
-
+ if (curbatch == 0) /* if it is the first pass */
+ {
/*
* Check to see if first outer tuple was already fetched by
* ExecHashJoin() and not used yet.
@@ -559,7 +558,8 @@ ExecHashJoinOuterGetTuple(PlanState *outerNode,
hjstate->hj_FirstOuterTupleSlot = NULL;
else
slot = ExecProcNode(outerNode);
- if (!TupIsNull(slot))
+
+ while (!TupIsNull(slot))
{
/*
* We have to compute the tuple's hash value.
@@ -567,13 +567,22 @@ ExecHashJoinOuterGetTuple(PlanState *outerNode,
ExprContext *econtext = hjstate->js.ps.ps_ExprContext;
econtext->ecxt_outertuple = slot;
- *hashvalue = ExecHashGetHashValue(hashtable, econtext,
- hjstate->hj_OuterHashKeys);
+ if (ExecHashGetHashValue(hashtable, econtext,
+ hjstate->hj_OuterHashKeys,
+ (hjstate->js.jointype == JOIN_LEFT),
+ hashvalue))
+ {
+ /* remember outer relation is not empty for possible rescan */
+ hjstate->hj_OuterNotEmpty = true;
- /* remember outer relation is not empty for possible rescan */
- hjstate->hj_OuterNotEmpty = true;
+ return slot;
+ }
- return slot;
+ /*
+ * That tuple couldn't match because of a NULL, so discard it
+ * and continue with the next one.
+ */
+ slot = ExecProcNode(outerNode);
}
/*