mirror of
https://github.com/postgres/postgres.git
synced 2025-06-13 07:41:39 +03:00
Add support for cross-type hashing in hashed subplans (hashed IN/NOT IN cases
that aren't turned into true joins). Since this is the last missing bit of infrastructure, go ahead and fill out the hash integer_ops and float_ops opfamilies with cross-type operators. The operator family project is now DONE ... er, except for documentation ...
This commit is contained in:
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeSubplan.c,v 1.84 2007/02/02 00:07:03 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeSubplan.c,v 1.85 2007/02/06 02:59:11 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -139,7 +139,10 @@ ExecHashSubPlan(SubPlanState *node,
|
||||
if (slotNoNulls(slot))
|
||||
{
|
||||
if (node->havehashrows &&
|
||||
LookupTupleHashEntry(node->hashtable, slot, NULL) != NULL)
|
||||
FindTupleHashEntry(node->hashtable,
|
||||
slot,
|
||||
node->cur_eq_funcs,
|
||||
node->lhs_hash_funcs) != NULL)
|
||||
{
|
||||
ExecClearTuple(slot);
|
||||
return BoolGetDatum(true);
|
||||
@ -453,8 +456,8 @@ buildSubPlanHash(SubPlanState *node)
|
||||
|
||||
node->hashtable = BuildTupleHashTable(ncols,
|
||||
node->keyColIdx,
|
||||
node->eqfunctions,
|
||||
node->hashfunctions,
|
||||
node->tab_eq_funcs,
|
||||
node->tab_hash_funcs,
|
||||
nbuckets,
|
||||
sizeof(TupleHashEntryData),
|
||||
node->tablecxt,
|
||||
@ -472,8 +475,8 @@ buildSubPlanHash(SubPlanState *node)
|
||||
}
|
||||
node->hashnulls = BuildTupleHashTable(ncols,
|
||||
node->keyColIdx,
|
||||
node->eqfunctions,
|
||||
node->hashfunctions,
|
||||
node->tab_eq_funcs,
|
||||
node->tab_hash_funcs,
|
||||
nbuckets,
|
||||
sizeof(TupleHashEntryData),
|
||||
node->tablecxt,
|
||||
@ -573,9 +576,9 @@ findPartialMatch(TupleHashTable hashtable, TupleTableSlot *slot)
|
||||
while ((entry = ScanTupleHashTable(&hashiter)) != NULL)
|
||||
{
|
||||
ExecStoreMinimalTuple(entry->firstTuple, hashtable->tableslot, false);
|
||||
if (!execTuplesUnequal(hashtable->tableslot, slot,
|
||||
if (!execTuplesUnequal(slot, hashtable->tableslot,
|
||||
numCols, keyColIdx,
|
||||
hashtable->eqfunctions,
|
||||
hashtable->cur_eq_funcs,
|
||||
hashtable->tempcxt))
|
||||
return true;
|
||||
}
|
||||
@ -653,8 +656,10 @@ ExecInitSubPlan(SubPlanState *node, EState *estate, int eflags)
|
||||
node->tablecxt = NULL;
|
||||
node->innerecontext = NULL;
|
||||
node->keyColIdx = NULL;
|
||||
node->eqfunctions = NULL;
|
||||
node->hashfunctions = NULL;
|
||||
node->tab_hash_funcs = NULL;
|
||||
node->tab_eq_funcs = NULL;
|
||||
node->lhs_hash_funcs = NULL;
|
||||
node->cur_eq_funcs = NULL;
|
||||
|
||||
/*
|
||||
* create an EState for the subplan
|
||||
@ -781,8 +786,10 @@ ExecInitSubPlan(SubPlanState *node, EState *estate, int eflags)
|
||||
|
||||
lefttlist = righttlist = NIL;
|
||||
leftptlist = rightptlist = NIL;
|
||||
node->eqfunctions = (FmgrInfo *) palloc(ncols * sizeof(FmgrInfo));
|
||||
node->hashfunctions = (FmgrInfo *) palloc(ncols * sizeof(FmgrInfo));
|
||||
node->tab_hash_funcs = (FmgrInfo *) palloc(ncols * sizeof(FmgrInfo));
|
||||
node->tab_eq_funcs = (FmgrInfo *) palloc(ncols * sizeof(FmgrInfo));
|
||||
node->lhs_hash_funcs = (FmgrInfo *) palloc(ncols * sizeof(FmgrInfo));
|
||||
node->cur_eq_funcs = (FmgrInfo *) palloc(ncols * sizeof(FmgrInfo));
|
||||
i = 1;
|
||||
foreach(l, oplist)
|
||||
{
|
||||
@ -792,6 +799,7 @@ ExecInitSubPlan(SubPlanState *node, EState *estate, int eflags)
|
||||
Expr *expr;
|
||||
TargetEntry *tle;
|
||||
GenericExprState *tlestate;
|
||||
Oid rhs_eq_oper;
|
||||
Oid left_hashfn;
|
||||
Oid right_hashfn;
|
||||
|
||||
@ -827,18 +835,24 @@ ExecInitSubPlan(SubPlanState *node, EState *estate, int eflags)
|
||||
righttlist = lappend(righttlist, tlestate);
|
||||
rightptlist = lappend(rightptlist, tle);
|
||||
|
||||
/* Lookup the combining function */
|
||||
fmgr_info(opexpr->opfuncid, &node->eqfunctions[i - 1]);
|
||||
node->eqfunctions[i - 1].fn_expr = (Node *) opexpr;
|
||||
/* Lookup the equality function (potentially cross-type) */
|
||||
fmgr_info(opexpr->opfuncid, &node->cur_eq_funcs[i - 1]);
|
||||
node->cur_eq_funcs[i - 1].fn_expr = (Node *) opexpr;
|
||||
|
||||
/* Look up the equality function for the RHS type */
|
||||
if (!get_compatible_hash_operators(opexpr->opno,
|
||||
NULL, &rhs_eq_oper))
|
||||
elog(ERROR, "could not find compatible hash operator for operator %u",
|
||||
opexpr->opno);
|
||||
fmgr_info(get_opcode(rhs_eq_oper), &node->tab_eq_funcs[i - 1]);
|
||||
|
||||
/* 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);
|
||||
/* For the moment, not supporting cross-type cases */
|
||||
Assert(left_hashfn == right_hashfn);
|
||||
fmgr_info(right_hashfn, &node->hashfunctions[i - 1]);
|
||||
fmgr_info(left_hashfn, &node->lhs_hash_funcs[i - 1]);
|
||||
fmgr_info(right_hashfn, &node->tab_hash_funcs[i - 1]);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
Reference in New Issue
Block a user