Thread: Hash support for row types

Hash support for row types

From
Peter Eisentraut
Date:
In [0] it was discussed that hash support for row types/record would be 
handy.  So I implemented that.

The implementation hashes each field and combines the hash values.  Most 
of the code structure can be borrowed from the record comparison 
functions/btree support.  To combine the hash values, I adapted the code 
from the array hashing functions.  (The hash_combine()/hash_combine64() 
functions also looked sensible, but they don't appear to work in a way 
that satisfies the hash_func regression test.  Could be documented better.)

The main motivation is to support UNION [DISTINCT] as discussed in [0], 
but this also enables other hash-related functionality such as hash 
joins (as one regression test accidentally revealed) and hash partitioning.


[0]: 

https://www.postgresql.org/message-id/flat/52beaf44-ccc3-0ba1-45c7-74aa251cd6ab%402ndquadrant.com#9559845e0ee2129c483b745b9843c571

-- 
Peter Eisentraut              http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

Attachment

Re: Hash support for row types

From
Andres Freund
Date:
Hi,

On 2020-10-19 10:01:14 +0200, Peter Eisentraut wrote:
> In [0] it was discussed that hash support for row types/record would be
> handy.  So I implemented that.

> The implementation hashes each field and combines the hash values.  Most of
> the code structure can be borrowed from the record comparison
> functions/btree support.  To combine the hash values, I adapted the code
> from the array hashing functions.  (The hash_combine()/hash_combine64()
> functions also looked sensible, but they don't appear to work in a way that
> satisfies the hash_func regression test.  Could be documented better.)
> 
> The main motivation is to support UNION [DISTINCT] as discussed in [0], but
> this also enables other hash-related functionality such as hash joins (as
> one regression test accidentally revealed) and hash partitioning.

How does this deal with row types with a field that doesn't have a hash
function? Erroring out at runtime could cause queries that used to
succeed, e.g. because all fields have btree ops, to fail, if we just have
a generic unconditionally present hash opclass?  Is that an OK
"regression"?

Greetings,

Andres Freund



Re: Hash support for row types

From
Peter Eisentraut
Date:
On 2020-10-20 01:32, Andres Freund wrote:
> How does this deal with row types with a field that doesn't have a hash
> function? Erroring out at runtime could cause queries that used to
> succeed, e.g. because all fields have btree ops, to fail, if we just have
> a generic unconditionally present hash opclass?  Is that an OK
> "regression"?

Good point.  There is actually code in the type cache that is supposed 
to handle that, so I'll need to adjust that.

-- 
Peter Eisentraut              http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services



Re: Hash support for row types

From
Robert Haas
Date:
On Tue, Oct 20, 2020 at 11:10 AM Peter Eisentraut
<peter.eisentraut@2ndquadrant.com> wrote:
> On 2020-10-20 01:32, Andres Freund wrote:
> > How does this deal with row types with a field that doesn't have a hash
> > function? Erroring out at runtime could cause queries that used to
> > succeed, e.g. because all fields have btree ops, to fail, if we just have
> > a generic unconditionally present hash opclass?  Is that an OK
> > "regression"?
>
> Good point.  There is actually code in the type cache that is supposed
> to handle that, so I'll need to adjust that.

Do we need to worry about what happens if somebody modifies the
opclass/opfamily definitions?

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company



Re: Hash support for row types

From
Tom Lane
Date:
Robert Haas <robertmhaas@gmail.com> writes:
> Do we need to worry about what happens if somebody modifies the
> opclass/opfamily definitions?

There's a lot of places that you can break by doing that.  I'm not
too concerned about it.

            regards, tom lane



Re: Hash support for row types

From
Peter Eisentraut
Date:
On 2020-10-20 17:10, Peter Eisentraut wrote:
> On 2020-10-20 01:32, Andres Freund wrote:
>> How does this deal with row types with a field that doesn't have a hash
>> function? Erroring out at runtime could cause queries that used to
>> succeed, e.g. because all fields have btree ops, to fail, if we just have
>> a generic unconditionally present hash opclass?  Is that an OK
>> "regression"?
> 
> Good point.  There is actually code in the type cache that is supposed
> to handle that, so I'll need to adjust that.

Here is an updated patch with the type cache integration added.

To your point, this now checks each fields hashability before 
considering a row type as hashable.  It can still have run-time errors 
for untyped record datums, but that's not something we can do anything 
about.

-- 
Peter Eisentraut              http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

Attachment

Re: Hash support for row types

From
Tom Lane
Date:
Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:
> Here is an updated patch with the type cache integration added.

> To your point, this now checks each fields hashability before 
> considering a row type as hashable.  It can still have run-time errors 
> for untyped record datums, but that's not something we can do anything 
> about.

This looks good code-wise.  A couple small niggles on the tests:

* The new test in with.sql claims to be testing row hashing, but
it's not very apparent that any such thing actually happens.  Maybe
EXPLAIN the query, as well as execute it, to confirm that a
hash-based plan is used.

* Is it worth devising a test case in which hashing is not possible
because one of the columns isn't hashable?  I have mixed feelings
about this because the set of suitable column types may decrease
to empty over time, making it hard to maintain the test case.

I marked it RFC.

            regards, tom lane



Re: Hash support for row types

From
Peter Eisentraut
Date:
I wrote a new patch to add a lot more tests around hash-based plans. 
This is intended to apply separately from the other patch, and the other 
patch would then "flip" some of the test cases.

On 2020-11-13 20:51, Tom Lane wrote:
> * The new test in with.sql claims to be testing row hashing, but
> it's not very apparent that any such thing actually happens.  Maybe
> EXPLAIN the query, as well as execute it, to confirm that a
> hash-based plan is used.

The recursive union requires hashing, but this is not visible in the 
plan.  You only get an error if there is no hashing support for a type. 
I have added a test for this.

For the non-recursive union, I have added more tests that show this in 
the plans.

> * Is it worth devising a test case in which hashing is not possible
> because one of the columns isn't hashable?  I have mixed feelings
> about this because the set of suitable column types may decrease
> to empty over time, making it hard to maintain the test case.

I used the money type for now.  If someone adds hash support for that, 
we'll change it.  I don't think this will change too rapidly, though.

-- 
Peter Eisentraut
2ndQuadrant, an EDB company
https://www.2ndquadrant.com/

Attachment

Re: Hash support for row types

From
Tom Lane
Date:
Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:
> I wrote a new patch to add a lot more tests around hash-based plans. 
> This is intended to apply separately from the other patch, and the other 
> patch would then "flip" some of the test cases.

OK, that addresses my concerns.

            regards, tom lane



Re: Hash support for row types

From
Peter Eisentraut
Date:
On 2020-11-17 20:33, Tom Lane wrote:
> Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:
>> I wrote a new patch to add a lot more tests around hash-based plans.
>> This is intended to apply separately from the other patch, and the other
>> patch would then "flip" some of the test cases.
> 
> OK, that addresses my concerns.

Thanks.  I have committed the tests and then subsequently the feature patch.

-- 
Peter Eisentraut
2ndQuadrant, an EDB company
https://www.2ndquadrant.com/