aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeHash.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2016-02-07 12:29:17 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2016-02-07 12:29:32 -0500
commitf867ce5518202a4e625dc41b7036fec47ee0e09e (patch)
treef8037946270665ccd4222d3810c3fa402526cf93 /src/backend/executor/nodeHash.c
parentd89f06f0482458d4b76e3be67ea428fec2a0aeb6 (diff)
downloadpostgresql-f867ce5518202a4e625dc41b7036fec47ee0e09e.tar.gz
postgresql-f867ce5518202a4e625dc41b7036fec47ee0e09e.zip
ExecHashRemoveNextSkewBucket must physically copy tuples to main hashtable.
Commit 45f6240a8fa9d355 added an assumption in ExecHashIncreaseNumBatches and ExecHashIncreaseNumBuckets that they could find all tuples in the main hash table by iterating over the "dense storage" introduced by that patch. However, ExecHashRemoveNextSkewBucket continued its old practice of simply re-linking deleted skew tuples into the main table's hashchains. Hence, such tuples got lost during any subsequent increase in nbatch or nbuckets, and would never get joined, as reported in bug #13908 from Seth P. I (tgl) think that the aforesaid commit has got multiple design issues and should be reworked rather completely; but there is no time for that right now, so band-aid the problem by making ExecHashRemoveNextSkewBucket physically copy deleted skew tuples into the "dense storage" arena. The added test case is able to exhibit the problem by means of fooling the planner with a WHERE condition that it will underestimate the selectivity of, causing the initial nbatch estimate to be too small. Tomas Vondra and Tom Lane. Thanks to David Johnston for initial investigation into the bug report.
Diffstat (limited to 'src/backend/executor/nodeHash.c')
-rw-r--r--src/backend/executor/nodeHash.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 47160e4aa07..9ed09a7b0ca 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -1575,8 +1575,19 @@ ExecHashRemoveNextSkewBucket(HashJoinTable hashtable)
if (batchno == hashtable->curbatch)
{
/* Move the tuple to the main hash table */
- hashTuple->next = hashtable->buckets[bucketno];
- hashtable->buckets[bucketno] = hashTuple;
+ HashJoinTuple copyTuple;
+
+ /*
+ * We must copy the tuple into the dense storage, else it will not
+ * be found by, eg, ExecHashIncreaseNumBatches.
+ */
+ copyTuple = (HashJoinTuple) dense_alloc(hashtable, tupleSize);
+ memcpy(copyTuple, hashTuple, tupleSize);
+ pfree(hashTuple);
+
+ copyTuple->next = hashtable->buckets[bucketno];
+ hashtable->buckets[bucketno] = copyTuple;
+
/* We have reduced skew space, but overall space doesn't change */
hashtable->spaceUsedSkew -= tupleSize;
}