Thread: Re: [COMMITTERS] pgsql: Add hash partitioning.

Re: [COMMITTERS] pgsql: Add hash partitioning.

From
Robert Haas
Date:
On Mon, Nov 13, 2017 at 3:24 AM, amul sul <sulamul@gmail.com> wrote:
> Updated patch attached -- Adjusted code comment to survive against pgindent.

That's not the right fix, or at least it's not complete.  You
shouldn't call PG_GETARG_...(n) until you've verified that
PG_ARGISNULL(n) returns false.

Also, I don't think moving the heap_open() earlier helps anything, but
you do need to replace Assert(key->partnatts == nkeys) with an
ereport() -- or just return false, but I think ereport() is probably
better.  Otherwise someone calling satisfies_hash_function() with a
wrong number of arguments for the partitioned table can cause an
assertion failure, which is bad.

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


Re: [COMMITTERS] pgsql: Add hash partitioning.

From
Michael Paquier
Date:
On Tue, Nov 14, 2017 at 3:59 AM, Robert Haas <robertmhaas@gmail.com> wrote:
> On Mon, Nov 13, 2017 at 3:24 AM, amul sul <sulamul@gmail.com> wrote:
>> Updated patch attached -- Adjusted code comment to survive against pgindent.
>
> That's not the right fix, or at least it's not complete.  You
> shouldn't call PG_GETARG_...(n) until you've verified that
> PG_ARGISNULL(n) returns false.
>
> Also, I don't think moving the heap_open() earlier helps anything, but
> you do need to replace Assert(key->partnatts == nkeys) with an
> ereport() -- or just return false, but I think ereport() is probably
> better.  Otherwise someone calling satisfies_hash_function() with a
> wrong number of arguments for the partitioned table can cause an
> assertion failure, which is bad.

Yeah, this patch needs more work. There is no need to do much efforts
on HEAD to crash it:
=# create table aa (a int);
CREATE TABLE
=# select satisfies_hash_partition('aa'::regclass, 0, NULL, 'po');
server closed the connection unexpectedly   This probably means the server terminated abnormally   before or while
processingthe request.
 

Could you add regression tests calling directly this function?

elog() can also be triggered easily, which should not happen with
user-callable functions:
=# select satisfies_hash_partition(0, 0, NULL, 'po');
ERROR:  XX000: could not open relation with OID 0

Thanks,
-- 
Michael


Re: [COMMITTERS] pgsql: Add hash partitioning.

From
amul sul
Date:
Thanks, Michael & Robert for your suggestions, and apologize for
delayed response

On Tue, Nov 14, 2017 at 6:02 AM, Michael Paquier
<michael.paquier@gmail.com> wrote:
> On Tue, Nov 14, 2017 at 3:59 AM, Robert Haas <robertmhaas@gmail.com> wrote:
>> On Mon, Nov 13, 2017 at 3:24 AM, amul sul <sulamul@gmail.com> wrote:
>>> Updated patch attached -- Adjusted code comment to survive against pgindent.
>>
>> That's not the right fix, or at least it's not complete.  You
>> shouldn't call PG_GETARG_...(n) until you've verified that
>> PG_ARGISNULL(n) returns false.
>>
>> Also, I don't think moving the heap_open() earlier helps anything, but
>> you do need to replace Assert(key->partnatts == nkeys) with an
>> ereport() -- or just return false, but I think ereport() is probably
>> better.  Otherwise someone calling satisfies_hash_function() with a
>> wrong number of arguments for the partitioned table can cause an
>> assertion failure, which is bad.
>

Understood, fixed in the 001 patch.

> Yeah, this patch needs more work. There is no need to do much efforts
> on HEAD to crash it:
> =# create table aa (a int);
> CREATE TABLE
> =# select satisfies_hash_partition('aa'::regclass, 0, NULL, 'po');
> server closed the connection unexpectedly
>     This probably means the server terminated abnormally
>     before or while processing the request.
>

Fixed in the 001 patch.

> Could you add regression tests calling directly this function?
>

Yes sure, but I am not sure that we really need this and also not sure about
which regression file is well suitable for these tests (to be honest, I haven't
browsed regression directory in detail due to lack of time today), so created
new file in 002 patch which is WIP.

Do let me know your thoughts will try to improve 0002 patch, tomorrow.

> elog() can also be triggered easily, which should not happen with
> user-callable functions:
> =# select satisfies_hash_partition(0, 0, NULL, 'po');
> ERROR:  XX000: could not open relation with OID 0
>

Fixed in the 001 patch.

IMHO, this function is not meant for a user, so that instead of ereport() cant
we simply return false?  TWIW, I have attached 003 patch which replaces all
erepots() by return false.

Regards,
Amul Sul

Attachment

Re: [COMMITTERS] pgsql: Add hash partitioning.

From
Robert Haas
Date:
On Thu, Nov 16, 2017 at 9:37 AM, amul sul <sulamul@gmail.com> wrote:
> Fixed in the 001 patch.
>
> IMHO, this function is not meant for a user, so that instead of ereport() cant
> we simply return false?  TWIW, I have attached 003 patch which replaces all
> erepots() by return false.

I don't think just returning false is very helpful behavior, because
the user may not realize that the problem is that the function is
being called incorrectly rather than that the call is correct and the
answer is false.

I took your 0001 patch and made extensive modifications to it.  I
replaced your regression tests from 0002 with a new set that I wrote
myself.  The result is attached here.  This version makes different
decisions about how to handle the various problem cases than you did;
it returns NULL for a NULL input or an OID for which no relation
exists, and throws specific error messages for the other cases,
matching the parser error messages that CREATE TABLE would issue where
possible, but with a different error code.  It also checks that the
types match (which your patch did not, and which I'm fairly sure could
crash the server), makes the function work when invoked using the
explicit VARIADIC syntax (which seems fairly useless here but there's
no in-core precedent for variadic function which doesn't support that
case), and fixes the function header comment to describe the behavior
we committed rather than the older behavior you had in earlier patch
versions.

As far as I can tell, this should nail things down pretty tight, but
it would be great if someone can try to find a case where it still
breaks.

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

Attachment

Re: [COMMITTERS] pgsql: Add hash partitioning.

From
amul sul
Date:
On Sat, Nov 18, 2017 at 1:19 AM, Robert Haas <robertmhaas@gmail.com> wrote:
> On Thu, Nov 16, 2017 at 9:37 AM, amul sul <sulamul@gmail.com> wrote:
>> Fixed in the 001 patch.
>>
>> IMHO, this function is not meant for a user, so that instead of ereport() cant
>> we simply return false?  TWIW, I have attached 003 patch which replaces all
>> erepots() by return false.
>
> I don't think just returning false is very helpful behavior, because
> the user may not realize that the problem is that the function is
> being called incorrectly rather than that the call is correct and the
> answer is false.
>
> I took your 0001 patch and made extensive modifications to it.  I
> replaced your regression tests from 0002 with a new set that I wrote
> myself.  The result is attached here.  This version makes different
> decisions about how to handle the various problem cases than you did;
> it returns NULL for a NULL input or an OID for which no relation
> exists, and throws specific error messages for the other cases,
> matching the parser error messages that CREATE TABLE would issue where
> possible, but with a different error code.  It also checks that the
> types match (which your patch did not, and which I'm fairly sure could
> crash the server), makes the function work when invoked using the
> explicit VARIADIC syntax (which seems fairly useless here but there's
> no in-core precedent for variadic function which doesn't support that
> case), and fixes the function header comment to describe the behavior
> we committed rather than the older behavior you had in earlier patch
> versions.
>
> As far as I can tell, this should nail things down pretty tight, but
> it would be great if someone can try to find a case where it still
> breaks.
>

Thanks for fixing this function.  Patch looks good to me, except column number
in the following errors message should to be 2.

354 +SELECT satisfies_hash_partition('mchash'::regclass, 2, 1,
NULL::int, NULL::int);
355 +ERROR:  column 1 of the partition key has type "text", but
supplied value is of type "integer"

Same at the line # 374 & 401 in the patch.

Regards,
Amul


Re: [COMMITTERS] pgsql: Add hash partitioning.

From
Robert Haas
Date:
On Mon, Nov 20, 2017 at 7:46 AM, amul sul <sulamul@gmail.com> wrote:
> Thanks for fixing this function.  Patch looks good to me, except column number
> in the following errors message should to be 2.
>
> 354 +SELECT satisfies_hash_partition('mchash'::regclass, 2, 1,
> NULL::int, NULL::int);
> 355 +ERROR:  column 1 of the partition key has type "text", but
> supplied value is of type "integer"
>
> Same at the line # 374 & 401 in the patch.

Oops.  Looks like the indexing should be 1-based rather than 0-based.
Committed with that change.

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