1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-05 07:21:24 +03:00

Add support for cross-type hashing in hash index searches and hash joins.

Hashing for aggregation purposes still needs work, so it's not time to
mark any cross-type operators as hashable for general use, but these cases
work if the operators are so marked by hand in the system catalogs.
This commit is contained in:
Tom Lane
2007-01-30 01:33:36 +00:00
parent e8cd6f14a2
commit a635c08fa1
12 changed files with 240 additions and 82 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/nodeHash.c,v 1.109 2007/01/28 23:21:26 tgl Exp $
* $PostgreSQL: pgsql/src/backend/executor/nodeHash.c,v 1.110 2007/01/30 01:33:36 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -94,7 +94,7 @@ MultiExecHash(HashState *node)
break;
/* We have to compute the hash value */
econtext->ecxt_innertuple = slot;
if (ExecHashGetHashValue(hashtable, econtext, hashkeys, false,
if (ExecHashGetHashValue(hashtable, econtext, hashkeys, false, false,
&hashvalue))
{
ExecHashTableInsert(hashtable, slot, hashvalue);
@ -267,19 +267,23 @@ ExecHashTableCreate(Hash *node, List *hashOperators)
* Also remember whether the join operators are strict.
*/
nkeys = list_length(hashOperators);
hashtable->hashfunctions = (FmgrInfo *) palloc(nkeys * sizeof(FmgrInfo));
hashtable->outer_hashfunctions =
(FmgrInfo *) palloc(nkeys * sizeof(FmgrInfo));
hashtable->inner_hashfunctions =
(FmgrInfo *) palloc(nkeys * sizeof(FmgrInfo));
hashtable->hashStrict = (bool *) palloc(nkeys * sizeof(bool));
i = 0;
foreach(ho, hashOperators)
{
Oid hashop = lfirst_oid(ho);
Oid hashfn;
Oid left_hashfn;
Oid right_hashfn;
hashfn = get_op_hash_function(hashop);
if (!OidIsValid(hashfn))
if (!get_op_hash_functions(hashop, &left_hashfn, &right_hashfn))
elog(ERROR, "could not find hash function for hash operator %u",
hashop);
fmgr_info(hashfn, &hashtable->hashfunctions[i]);
fmgr_info(left_hashfn, &hashtable->outer_hashfunctions[i]);
fmgr_info(right_hashfn, &hashtable->inner_hashfunctions[i]);
hashtable->hashStrict[i] = op_strict(hashop);
i++;
}
@ -674,10 +678,12 @@ bool
ExecHashGetHashValue(HashJoinTable hashtable,
ExprContext *econtext,
List *hashkeys,
bool outer_tuple,
bool keep_nulls,
uint32 *hashvalue)
{
uint32 hashkey = 0;
FmgrInfo *hashfunctions;
ListCell *hk;
int i = 0;
MemoryContext oldContext;
@ -690,6 +696,11 @@ ExecHashGetHashValue(HashJoinTable hashtable,
oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
if (outer_tuple)
hashfunctions = hashtable->outer_hashfunctions;
else
hashfunctions = hashtable->inner_hashfunctions;
foreach(hk, hashkeys)
{
ExprState *keyexpr = (ExprState *) lfirst(hk);
@ -728,8 +739,7 @@ ExecHashGetHashValue(HashJoinTable hashtable,
/* Compute the hash function */
uint32 hkey;
hkey = DatumGetUInt32(FunctionCall1(&hashtable->hashfunctions[i],
keyval));
hkey = DatumGetUInt32(FunctionCall1(&hashfunctions[i], keyval));
hashkey ^= hkey;
}