Teach hash_ok_operator() that record_eq is only sometimes hashable.

The need for this was foreseen long ago, but when record_eq
actually became hashable (in commit 01e658fa7), we missed updating
this spot.

Per bug #17363 from Elvis Pranskevichus.  Back-patch to v14 where
the faulty commit came in.

Discussion: https://postgr.es/m/17363-f6d42fd0d726be02@postgresql.org
This commit is contained in:
Tom Lane 2022-01-16 16:39:26 -05:00
parent fe75517443
commit 6478896675
3 changed files with 36 additions and 3 deletions

View File

@ -848,10 +848,10 @@ hash_ok_operator(OpExpr *expr)
/* quick out if not a binary operator */
if (list_length(expr->args) != 2)
return false;
if (opid == ARRAY_EQ_OP)
if (opid == ARRAY_EQ_OP ||
opid == RECORD_EQ_OP)
{
/* array_eq is strict, but must check input type to ensure hashable */
/* XXX record_eq will need same treatment when it becomes hashable */
/* these are strict, but must check input type to ensure hashable */
Node *leftarg = linitial(expr->args);
return op_hashjoinable(opid, exprType(leftarg));

View File

@ -789,6 +789,29 @@ select 'foo'::text in (select 'bar'::name union all select 'bar'::name);
f
(1 row)
--
-- Test that we don't try to hash nested records (bug #17363)
-- (Hashing could be supported, but for now we don't)
--
explain (verbose, costs off)
select row(row(row(1))) = any (select row(row(1)));
QUERY PLAN
-------------------------------------------
Result
Output: (SubPlan 1)
SubPlan 1
-> Materialize
Output: '("(1)")'::record
-> Result
Output: '("(1)")'::record
(7 rows)
select row(row(row(1))) = any (select row(row(1)));
?column?
----------
t
(1 row)
--
-- Test case for premature memory release during hashing of subplan output
--

View File

@ -463,6 +463,16 @@ select 'foo'::text in (select 'bar'::name union all select 'bar'::name);
select 'foo'::text in (select 'bar'::name union all select 'bar'::name);
--
-- Test that we don't try to hash nested records (bug #17363)
-- (Hashing could be supported, but for now we don't)
--
explain (verbose, costs off)
select row(row(row(1))) = any (select row(row(1)));
select row(row(row(1))) = any (select row(row(1)));
--
-- Test case for premature memory release during hashing of subplan output
--