Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4816d2e

Browse files
committed
Fix cross-type case in partial row matching for hashed subplans.
When hashing a subplan like "WHERE (a, b) NOT IN (SELECT x, y FROM ...)",findPartialMatch() attempted to match rows using the hashtable's internalequality operators, which of course are for x and y's datatypes. What weneed to use are the potentially cross-type operators for a=x, b=y, etc.Failure to do that leads to wrong answers or even crashes. The scope forproblems is limited to cases where we have different types with compatiblehash functions (else we'd not be using a hashed subplan), but for exampleint4 vs int8 can cause the problem.Per bug #7597 from Bo Jensen. This has been wrong since the hashed-subplancode was written, so patch all the way back.
1 parent6f60fdd commit4816d2e

File tree

3 files changed

+43
-6
lines changed

3 files changed

+43
-6
lines changed

‎src/backend/executor/nodeSubplan.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ static Datum ExecScanSubPlan(SubPlanState *node,
4646
ExprContext*econtext,
4747
bool*isNull);
4848
staticvoidbuildSubPlanHash(SubPlanState*node,ExprContext*econtext);
49-
staticboolfindPartialMatch(TupleHashTablehashtable,TupleTableSlot*slot);
49+
staticboolfindPartialMatch(TupleHashTablehashtable,TupleTableSlot*slot,
50+
FmgrInfo*eqfunctions);
5051
staticboolslotAllNulls(TupleTableSlot*slot);
5152
staticboolslotNoNulls(TupleTableSlot*slot);
5253

@@ -153,7 +154,7 @@ ExecHashSubPlan(SubPlanState *node,
153154
returnBoolGetDatum(true);
154155
}
155156
if (node->havenullrows&&
156-
findPartialMatch(node->hashnulls,slot))
157+
findPartialMatch(node->hashnulls,slot,node->cur_eq_funcs))
157158
{
158159
ExecClearTuple(slot);
159160
*isNull= true;
@@ -186,14 +187,14 @@ ExecHashSubPlan(SubPlanState *node,
186187
}
187188
/* Scan partly-null table first, since more likely to get a match */
188189
if (node->havenullrows&&
189-
findPartialMatch(node->hashnulls,slot))
190+
findPartialMatch(node->hashnulls,slot,node->cur_eq_funcs))
190191
{
191192
ExecClearTuple(slot);
192193
*isNull= true;
193194
returnBoolGetDatum(false);
194195
}
195196
if (node->havehashrows&&
196-
findPartialMatch(node->hashtable,slot))
197+
findPartialMatch(node->hashtable,slot,node->cur_eq_funcs))
197198
{
198199
ExecClearTuple(slot);
199200
*isNull= true;
@@ -573,9 +574,13 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext)
573574
* We have to scan the whole hashtable; we can't usefully use hashkeys
574575
* to guide probing, since we might get partial matches on tuples with
575576
* hashkeys quite unrelated to what we'd get from the given tuple.
577+
*
578+
* Caller must provide the equality functions to use, since in cross-type
579+
* cases these are different from the hashtable's internal functions.
576580
*/
577581
staticbool
578-
findPartialMatch(TupleHashTablehashtable,TupleTableSlot*slot)
582+
findPartialMatch(TupleHashTablehashtable,TupleTableSlot*slot,
583+
FmgrInfo*eqfunctions)
579584
{
580585
intnumCols=hashtable->numCols;
581586
AttrNumber*keyColIdx=hashtable->keyColIdx;
@@ -588,7 +593,7 @@ findPartialMatch(TupleHashTable hashtable, TupleTableSlot *slot)
588593
ExecStoreMinimalTuple(entry->firstTuple,hashtable->tableslot, false);
589594
if (!execTuplesUnequal(slot,hashtable->tableslot,
590595
numCols,keyColIdx,
591-
hashtable->cur_eq_funcs,
596+
eqfunctions,
592597
hashtable->tempcxt))
593598
{
594599
TermTupleHashIterator(&hashiter);

‎src/test/regress/expected/subselect.out

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,23 @@ from
543543
-----
544544
(0 rows)
545545

546+
--
547+
-- Test case for cross-type partial matching in hashed subplan (bug #7597)
548+
--
549+
create temp table outer_7597 (f1 int4, f2 int4);
550+
insert into outer_7597 values (0, 0);
551+
insert into outer_7597 values (1, 0);
552+
insert into outer_7597 values (0, null);
553+
insert into outer_7597 values (1, null);
554+
create temp table inner_7597(c1 int8, c2 int8);
555+
insert into inner_7597 values(0, null);
556+
select * from outer_7597 where (f1, f2) not in (select * from inner_7597);
557+
f1 | f2
558+
----+----
559+
1 | 0
560+
1 |
561+
(2 rows)
562+
546563
--
547564
-- Test case for premature memory release during hashing of subplan output
548565
--

‎src/test/regress/sql/subselect.sql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,21 @@ from
345345
join
346346
int4_tbl i4on dummy=i4.f1;
347347

348+
--
349+
-- Test case for cross-type partial matching in hashed subplan (bug #7597)
350+
--
351+
352+
create temp table outer_7597 (f1 int4, f2 int4);
353+
insert into outer_7597values (0,0);
354+
insert into outer_7597values (1,0);
355+
insert into outer_7597values (0,null);
356+
insert into outer_7597values (1,null);
357+
358+
create temp table inner_7597(c1 int8, c2 int8);
359+
insert into inner_7597values(0,null);
360+
361+
select*from outer_7597where (f1, f2) notin (select*from inner_7597);
362+
348363
--
349364
-- Test case for premature memory release during hashing of subplan output
350365
--

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp