ExprContext *econtext,
bool *isNull);
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 slotNoNulls(TupleTableSlot *slot);
return BoolGetDatum(true);
}
if (node->havenullrows &&
- findPartialMatch(node->hashnulls, slot))
+ findPartialMatch(node->hashnulls, slot, node->cur_eq_funcs))
{
ExecClearTuple(slot);
*isNull = true;
}
/* Scan partly-null table first, since more likely to get a match */
if (node->havenullrows &&
- findPartialMatch(node->hashnulls, slot))
+ findPartialMatch(node->hashnulls, slot, node->cur_eq_funcs))
{
ExecClearTuple(slot);
*isNull = true;
return BoolGetDatum(false);
}
if (node->havehashrows &&
- findPartialMatch(node->hashtable, slot))
+ findPartialMatch(node->hashtable, slot, node->cur_eq_funcs))
{
ExecClearTuple(slot);
*isNull = true;
* 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
* 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
-findPartialMatch(TupleHashTable hashtable, TupleTableSlot *slot)
+findPartialMatch(TupleHashTable hashtable, TupleTableSlot *slot,
+ FmgrInfo *eqfunctions)
{
int numCols = hashtable->numCols;
AttrNumber *keyColIdx = hashtable->keyColIdx;
ExecStoreMinimalTuple(entry->firstTuple, hashtable->tableslot, false);
if (!execTuplesUnequal(slot, hashtable->tableslot,
numCols, keyColIdx,
- hashtable->cur_eq_funcs,
+ eqfunctions,
hashtable->tempcxt))
{
TermTupleHashIterator(&hashiter);
-----
(0 rows)
+--
+-- Test case for cross-type partial matching in hashed subplan (bug #7597)
+--
+create temp table outer_7597 (f1 int4, f2 int4);
+insert into outer_7597 values (0, 0);
+insert into outer_7597 values (1, 0);
+insert into outer_7597 values (0, null);
+insert into outer_7597 values (1, null);
+create temp table inner_7597(c1 int8, c2 int8);
+insert into inner_7597 values(0, null);
+select * from outer_7597 where (f1, f2) not in (select * from inner_7597);
+ f1 | f2
+----+----
+ 1 | 0
+ 1 |
+(2 rows)
+
--
-- Test case for premature memory release during hashing of subplan output
--
join
int4_tbl i4 on dummy = i4.f1;
+--
+-- Test case for cross-type partial matching in hashed subplan (bug #7597)
+--
+
+create temp table outer_7597 (f1 int4, f2 int4);
+insert into outer_7597 values (0, 0);
+insert into outer_7597 values (1, 0);
+insert into outer_7597 values (0, null);
+insert into outer_7597 values (1, null);
+
+create temp table inner_7597(c1 int8, c2 int8);
+insert into inner_7597 values(0, null);
+
+select * from outer_7597 where (f1, f2) not in (select * from inner_7597);
+
--
-- Test case for premature memory release during hashing of subplan output
--