mirror of
https://github.com/postgres/postgres.git
synced 2025-06-30 21:42:05 +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:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execGrouping.c,v 1.23 2007/01/10 18:06:02 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execGrouping.c,v 1.24 2007/01/30 01:33:36 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -224,15 +224,18 @@ execTuplesHashPrepare(int numCols,
|
||||
{
|
||||
Oid eq_opr = eqOperators[i];
|
||||
Oid eq_function;
|
||||
Oid hash_function;
|
||||
Oid left_hash_function;
|
||||
Oid right_hash_function;
|
||||
|
||||
eq_function = get_opcode(eq_opr);
|
||||
hash_function = get_op_hash_function(eq_opr);
|
||||
if (!OidIsValid(hash_function)) /* should not happen */
|
||||
if (!get_op_hash_functions(eq_opr,
|
||||
&left_hash_function, &right_hash_function))
|
||||
elog(ERROR, "could not find hash function for hash operator %u",
|
||||
eq_opr);
|
||||
/* For the moment, we're not supporting cross-type cases here */
|
||||
Assert(left_hash_function == right_hash_function);
|
||||
fmgr_info(eq_function, &(*eqFunctions)[i]);
|
||||
fmgr_info(hash_function, &(*hashFunctions)[i]);
|
||||
fmgr_info(right_hash_function, &(*hashFunctions)[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeHashjoin.c,v 1.87 2007/01/28 23:21:26 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeHashjoin.c,v 1.88 2007/01/30 01:33:36 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -569,6 +569,7 @@ ExecHashJoinOuterGetTuple(PlanState *outerNode,
|
||||
econtext->ecxt_outertuple = slot;
|
||||
if (ExecHashGetHashValue(hashtable, econtext,
|
||||
hjstate->hj_OuterHashKeys,
|
||||
true, /* outer tuple */
|
||||
(hjstate->js.jointype == JOIN_LEFT),
|
||||
hashvalue))
|
||||
{
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeSubplan.c,v 1.82 2007/01/05 22:19:28 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeSubplan.c,v 1.83 2007/01/30 01:33:36 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -792,7 +792,8 @@ ExecInitSubPlan(SubPlanState *node, EState *estate, int eflags)
|
||||
Expr *expr;
|
||||
TargetEntry *tle;
|
||||
GenericExprState *tlestate;
|
||||
Oid hashfn;
|
||||
Oid left_hashfn;
|
||||
Oid right_hashfn;
|
||||
|
||||
Assert(IsA(fstate, FuncExprState));
|
||||
Assert(IsA(opexpr, OpExpr));
|
||||
@ -830,12 +831,14 @@ ExecInitSubPlan(SubPlanState *node, EState *estate, int eflags)
|
||||
fmgr_info(opexpr->opfuncid, &node->eqfunctions[i - 1]);
|
||||
node->eqfunctions[i - 1].fn_expr = (Node *) opexpr;
|
||||
|
||||
/* Lookup the associated hash function */
|
||||
hashfn = get_op_hash_function(opexpr->opno);
|
||||
if (!OidIsValid(hashfn))
|
||||
/* Lookup the associated hash functions */
|
||||
if (!get_op_hash_functions(opexpr->opno,
|
||||
&left_hashfn, &right_hashfn))
|
||||
elog(ERROR, "could not find hash function for hash operator %u",
|
||||
opexpr->opno);
|
||||
fmgr_info(hashfn, &node->hashfunctions[i - 1]);
|
||||
/* For the moment, not supporting cross-type cases */
|
||||
Assert(left_hashfn == right_hashfn);
|
||||
fmgr_info(right_hashfn, &node->hashfunctions[i - 1]);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
Reference in New Issue
Block a user