summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2022-01-16 21:39:26 +0000
committerTom Lane2022-01-16 21:39:26 +0000
commit6478896675660402171c97d6307e6e1519250025 (patch)
tree1cc838e570e2c916ac8601609e6eb48f01f8b6d6
parentfe75517443b7c38f5251d007d06321655ce6c0b6 (diff)
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/[email protected]
-rw-r--r--src/backend/optimizer/plan/subselect.c6
-rw-r--r--src/test/regress/expected/subselect.out23
-rw-r--r--src/test/regress/sql/subselect.sql10
3 files changed, 36 insertions, 3 deletions
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index 8c9408d372..41bd1ae7d4 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -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));
diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out
index 4e8ddc7061..45c75eecc5 100644
--- a/src/test/regress/expected/subselect.out
+++ b/src/test/regress/expected/subselect.out
@@ -790,6 +790,29 @@ select 'foo'::text in (select 'bar'::name union all select 'bar'::name);
(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
--
select '1'::text in (select '1'::name union all select '1'::name);
diff --git a/src/test/regress/sql/subselect.sql b/src/test/regress/sql/subselect.sql
index e879999708..94ba91f5bb 100644
--- a/src/test/regress/sql/subselect.sql
+++ b/src/test/regress/sql/subselect.sql
@@ -464,6 +464,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
--