Обсуждение: BUG #17363: 14 regression: "could not identify a hash function for type record" in a nested record in sublink
BUG #17363: 14 regression: "could not identify a hash function for type record" in a nested record in sublink
От
 
		    	PG Bug reporting form
		    Дата:
		        The following bug has been logged on the website:
Bug reference:      17363
Logged by:          Elvis Pranskevichus
Email address:      elprans@gmail.com
PostgreSQL version: 14.0
Operating system:   Linux
Description:
The following fails in PostgreSQL 14:
    postgres14=# SELECT ROW(ROW(ROW(1))) = ANY (SELECT
(ROW(ROW(ROW(1)))).*);
    ERROR:  could not identify a hash function for type record
whereas PostgreSQL 13 works fine:
    postgres13=# SELECT ROW(ROW(ROW(1))) = ANY (SELECT
(ROW(ROW(ROW(1)))).*);  
     ?column?
    ──────────
     t
    (1 row)
Interestingly, reducing the nesting level to two works in 14:
    postgres14=# SELECT ROW(ROW(1)) = ANY (SELECT (ROW(ROW(1))).*);
     ?column?
    ──────────
     t
    (1 row)
			
		PG Bug reporting form <noreply@postgresql.org> writes:
> The following fails in PostgreSQL 14:
>   postgres14=# SELECT ROW(ROW(ROW(1))) = ANY (SELECT (ROW(ROW(ROW(1)))).*);
>   ERROR:  could not identify a hash function for type record
> whereas PostgreSQL 13 works fine:
It appears that we're trying to use a hashed subplan for the =ANY,
where v13 did not.  So I'm inclined to blame this on 01e658fa7 (Hash
support for row types).  We backed off the optimism level a bit in
a3d2b1bbe (Disable anonymous record hash support except in special
cases), but evidently didn't go far enough; or else it's doing the
wrong thing for nested RECORD types.
            regards, tom lane
			
		I wrote:
> It appears that we're trying to use a hashed subplan for the =ANY,
> where v13 did not.  So I'm inclined to blame this on 01e658fa7 (Hash
> support for row types).  We backed off the optimism level a bit in
> a3d2b1bbe (Disable anonymous record hash support except in special
> cases), but evidently didn't go far enough; or else it's doing the
> wrong thing for nested RECORD types.
Ugh, found it: hash_ok_operator() is not accounting for this case.
    if (opid == ARRAY_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 */
        Node       *leftarg = linitial(expr->args);
        return op_hashjoinable(opid, exprType(leftarg));
    }
Will fix.
            regards, tom lane