*** pgsql/src/backend/executor/nodeHashjoin.c 2009/01/01 17:23:41 1.97 --- pgsql/src/backend/executor/nodeHashjoin.c 2009/03/21 00:04:38 1.98 *************** *** 8,14 **** * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/executor/nodeHashjoin.c,v 1.96 2008/10/23 14:34:34 tgl Exp $ * *------------------------------------------------------------------------- */ --- 8,14 ---- * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/executor/nodeHashjoin.c,v 1.97 2009/01/01 17:23:41 momjian Exp $ * *------------------------------------------------------------------------- */ *************** ExecHashJoin(HashJoinState *node) *** 198,216 **** node->hj_MatchedOuter = false; /* ! * now we have an outer tuple, find the corresponding bucket for ! * this tuple from the hash table */ node->hj_CurHashValue = hashvalue; ExecHashGetBucketAndBatch(hashtable, hashvalue, &node->hj_CurBucketNo, &batchno); node->hj_CurTuple = NULL; /* * Now we've got an outer tuple and the corresponding hash bucket, ! * but this tuple may not belong to the current batch. */ ! if (batchno != hashtable->curbatch) { /* * Need to postpone this outer tuple to a later batch. Save it --- 198,220 ---- node->hj_MatchedOuter = false; /* ! * Now we have an outer tuple; find the corresponding bucket for ! * this tuple in the main hash table or skew hash table. */ node->hj_CurHashValue = hashvalue; ExecHashGetBucketAndBatch(hashtable, hashvalue, &node->hj_CurBucketNo, &batchno); + node->hj_CurSkewBucketNo = ExecHashGetSkewBucket(hashtable, + hashvalue); node->hj_CurTuple = NULL; /* * Now we've got an outer tuple and the corresponding hash bucket, ! * but it might not belong to the current batch, or it might ! * match a skew bucket. */ ! if (batchno != hashtable->curbatch && ! node->hj_CurSkewBucketNo == INVALID_SKEW_BUCKET_NO) { /* * Need to postpone this outer tuple to a later batch. Save it *************** ExecInitHashJoin(HashJoin *node, EState *** 452,457 **** --- 456,462 ---- hjstate->hj_CurHashValue = 0; hjstate->hj_CurBucketNo = 0; + hjstate->hj_CurSkewBucketNo = INVALID_SKEW_BUCKET_NO; hjstate->hj_CurTuple = NULL; /* *************** start_over: *** 651,656 **** --- 656,674 ---- BufFileClose(hashtable->outerBatchFile[curbatch]); hashtable->outerBatchFile[curbatch] = NULL; } + else /* we just finished the first batch */ + { + /* + * Reset some of the skew optimization state variables, since we + * no longer need to consider skew tuples after the first batch. + * The memory context reset we are about to do will release the + * skew hashtable itself. + */ + hashtable->skewEnabled = false; + hashtable->skewBucket = NULL; + hashtable->skewBucketNums = NULL; + hashtable->spaceUsedSkew = 0; + } /* * We can always skip over any batches that are completely empty on both *************** ExecReScanHashJoin(HashJoinState *node, *** 880,885 **** --- 898,904 ---- /* Always reset intra-tuple state */ node->hj_CurHashValue = 0; node->hj_CurBucketNo = 0; + node->hj_CurSkewBucketNo = INVALID_SKEW_BUCKET_NO; node->hj_CurTuple = NULL; node->js.ps.ps_TupFromTlist = false;