@ -44,7 +44,8 @@ static Datum ExecScanSubPlan(SubPlanState *node,
ExprContext * econtext ,
ExprContext * econtext ,
bool * isNull ) ;
bool * isNull ) ;
static void buildSubPlanHash ( SubPlanState * node , ExprContext * econtext ) ;
static void buildSubPlanHash ( SubPlanState * node , ExprContext * econtext ) ;
static bool findPartialMatch ( TupleHashTable hashtable , TupleTableSlot * slot ) ;
static bool findPartialMatch ( TupleHashTable hashtable , TupleTableSlot * slot ,
FmgrInfo * eqfunctions ) ;
static bool slotAllNulls ( TupleTableSlot * slot ) ;
static bool slotAllNulls ( TupleTableSlot * slot ) ;
static bool slotNoNulls ( TupleTableSlot * slot ) ;
static bool slotNoNulls ( TupleTableSlot * slot ) ;
@ -151,7 +152,7 @@ ExecHashSubPlan(SubPlanState *node,
return BoolGetDatum ( true ) ;
return BoolGetDatum ( true ) ;
}
}
if ( node - > havenullrows & &
if ( node - > havenullrows & &
findPartialMatch ( node - > hashnulls , slot ) )
findPartialMatch ( node - > hashnulls , slot , node - > cur_eq_funcs ) )
{
{
ExecClearTuple ( slot ) ;
ExecClearTuple ( slot ) ;
* isNull = true ;
* isNull = true ;
@ -184,14 +185,14 @@ ExecHashSubPlan(SubPlanState *node,
}
}
/* Scan partly-null table first, since more likely to get a match */
/* Scan partly-null table first, since more likely to get a match */
if ( node - > havenullrows & &
if ( node - > havenullrows & &
findPartialMatch ( node - > hashnulls , slot ) )
findPartialMatch ( node - > hashnulls , slot , node - > cur_eq_funcs ) )
{
{
ExecClearTuple ( slot ) ;
ExecClearTuple ( slot ) ;
* isNull = true ;
* isNull = true ;
return BoolGetDatum ( false ) ;
return BoolGetDatum ( false ) ;
}
}
if ( node - > havehashrows & &
if ( node - > havehashrows & &
findPartialMatch ( node - > hashtable , slot ) )
findPartialMatch ( node - > hashtable , slot , node - > cur_eq_funcs ) )
{
{
ExecClearTuple ( slot ) ;
ExecClearTuple ( slot ) ;
* isNull = true ;
* isNull = true ;
@ -571,9 +572,13 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext)
* We have to scan the whole hashtable ; we can ' t usefully use hashkeys
* We have to scan the whole hashtable ; we can ' t usefully use hashkeys
* to guide probing , since we might get partial matches on tuples with
* to guide probing , since we might get partial matches on tuples with
* hashkeys quite unrelated to what we ' d get from the given tuple .
* hashkeys quite unrelated to what we ' d get from the given tuple .
*
* Caller must provide the equality functions to use , since in cross - type
* cases these are different from the hashtable ' s internal functions .
*/
*/
static bool
static bool
findPartialMatch ( TupleHashTable hashtable , TupleTableSlot * slot )
findPartialMatch ( TupleHashTable hashtable , TupleTableSlot * slot ,
FmgrInfo * eqfunctions )
{
{
int numCols = hashtable - > numCols ;
int numCols = hashtable - > numCols ;
AttrNumber * keyColIdx = hashtable - > keyColIdx ;
AttrNumber * keyColIdx = hashtable - > keyColIdx ;
@ -586,7 +591,7 @@ findPartialMatch(TupleHashTable hashtable, TupleTableSlot *slot)
ExecStoreMinimalTuple ( entry - > firstTuple , hashtable - > tableslot , false ) ;
ExecStoreMinimalTuple ( entry - > firstTuple , hashtable - > tableslot , false ) ;
if ( ! execTuplesUnequal ( slot , hashtable - > tableslot ,
if ( ! execTuplesUnequal ( slot , hashtable - > tableslot ,
numCols , keyColIdx ,
numCols , keyColIdx ,
hashtable - > cur_ eq_ funcs,
eqfunction s ,
hashtable - > tempcxt ) )
hashtable - > tempcxt ) )
{
{
TermTupleHashIterator ( & hashiter ) ;
TermTupleHashIterator ( & hashiter ) ;